dev@grizzly.java.net

Re: [2.0] Unifying Future

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Tue, 16 Dec 2008 13:31:58 -0500

Salut,

Oleksiy Stashok wrote:
>>
>>
>> Oleksiy Stashok wrote:
>>> Hi,
>>>>
>>>> I would like to propose a change to the current Grizzly 2.0 way of
>>>> using Future. Instead of having:
>>>>
>>>> IOFuture
>>>> ConnectFuture
>>>> ReadFuture
>>>> WriteFuture
>>> All these futures implement Future. Those classes just help us avoid
>>> using casting or generics. However even with current Grizzly 2.0
>>> implementation you can use just Future and don't care about its
>>> subclasses.
>>> Code:
>>> ConnectFuture future = connectionHandler.connect();
>>> Connection connection = future.get();
>>
>> Yes, but take a look at AIO:
>>
>> http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousSocketChannel.html
>>
>>
>> They do the same thing with a unified API :-) I would like us to do
>> the same.
> Grizzly API is more general.
> Grizzly's Connection.read/write may use transformers, which means, that
> result could be not just Integer, but any type.

That's an implementation details...we can also implement generics since
we also have CompletionHandler.


> For example, If you'll take a look at AIO DatagramChannel [1], there are
> 2 different methods write/send, read/receive; with Grizzly we will have
> just one.

Is it really what we want? How the user will know the difference between
receive vs read?



>
>
>>> is the same as:
>>> Future<Connection> future = connectionHandler.connect(...);
>>> Connection connection = future.get();
>>> The same situation with read and write. So, IMHO, it should be fine?
>>> It just depends on developer's style.
>>>> I would like to align with the API and remove the above classes and
>>>> instead add something like GrizzlyFuture. Looking at the code, the
>>>> specialized API added to the above classes can be replaced with
>>>>
>>>> public R get() // Instead of getResults, which return the same as
>>>> get anyway.
>>> getResult() is not the same as get(). getResult() returns result
>>> immediately, possibly null if result is not ready yet.
>>
>> Same as get(0,TimeUnits.SECONDS);
> Not sure it's the same.
> The latest may throw TimeoutException, if there is no result available.
> Which may be not desirable for us.

We are implementing the behavior, so I would think we never throw such
exception.


>
>>> V get(long timeout,
>>> TimeUnit unit)
>>
>> We should re-use that one instead.
>>
>>
>>
>>>> Same for getImmediateReadResult, getImmediateWriteResult, etc. which
>>>> can anyway get retrieved using Future.get().
>>> Again, it's not the same. ImmediateResult returns current operation
>>> state.
>>> iofuture.get() - returns final result. Will block until result is not
>>> ready
>>> iofuture.getResult() - returns final result. Will not block. If final
>>> result is not ready - null will be returned.
>>> iofuture.getImmediateResule() - returns current operation state.
>>
>> What does it means exactly? If I'm doing a read, what will I get?
> ReadResult, which contains: connection, result message, address we've
> received the message from (makes sense for UDP), number of bytes read.

The ReadResult could by augmented and returned when doing Future.get().
That way we are getting the same as the getXXX we have right now. Also
right now we have Read|WriteFuture.getConnection(), but we don't have it
for ConnectFuture. More, the xxxResults.getConnection() return the same.
So we have several way to achieve the same thing, which we don't want
(as we learned with grizzly 1.x).



>
>> Will
>>> not block. (Could be used for debugging for example).
>>
>> Hum...Do you have an example where it can be used in real? I'm not
>> convinced about "debugging purpose". I'm really not toward those API
>> right now unless we have a strong use case :-)
> Ok, if you have slow network or work with big chunk of data - you can
> always check how many bytes were read/write so far.

But that's a major issue if our CompletionHandler is invoked only when
we have read *all* the bytes. With HTTP, that will not works to buffer
the body in memory (will gives bad performance). Hence the
CompletionHandler must be called when bytes are available (or using some
rules). Then you can get that information from there and no need for
that API IMO.



  For GUI
> applications, which show current progress - it could make sense :)

Well, they can alwways get that with CompletionHandler. Now are the
CompletionHandler invoked only when all the bytes has been read?


>
>>>> The ConnectFuture doesn't add any API as well, which I found strange.
>>> Well, it was just added, because we have ReadFuture, WriteFuture...
>>> so the same I did for Accept and Connect I/O operations.
>>> But again, it's possible to use plain Future.

We need to unify all of those IMO. I'm +1 for pure Future, +0 for an
IOFuture, but -1 for Read/Write/Connect specialization :-)


>>>> What do you think?
>>> IMHO, current Grizzly implementation lets us work with Futures in
>>> unified way. So, probably we don't need to change anything here?
>>
>> I would still think we need to manipulate Future and not specialized
>> IOFuture. Note that we started jsr 203 with IOFuture and we dropped
>> them to only use Future. I think this is more clearer...
> But it is possible. As I mentioned above. It's not necessary at all to
> care about that. We can suppose, that all the IOFuture subclasses are
> just implementations of Future interface. And it's up to developer, if
> he wants to use interface Future or cast it to some subclass.

Hum :-) We either hides them of make them available. Not in-between :-).
We had way to much in-between in 1.x, most of them because of my bad
original design...let's work on reducing them at the minimum.

Let me read David's proposal :-)

A+

-- Jeanfrancois


>
> WBR,
> Alexey.
>
> [1]
> http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousDatagramChannel.html
>
>>
>>
>> A+
>>
>> -- Jeanfrancois
>>
>>
>>
>>> Thanks.
>>> WBR,
>>> Alexey.
>>>>
>>>>
>>>> A+
>>>>
>>>> -- Jeanfrancois
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
>>>> <mailto:dev-unsubscribe_at_grizzly.dev.java.net>
>>>> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>>>> <mailto:dev-help_at_grizzly.dev.java.net>
>>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>