users@grizzly.java.net

Re: Grizzly 2.0 as a client connection provider

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Mon, 30 Mar 2009 15:09:29 +0200

Hi,

>
> I am further along and the sending side makes sense. However, the
> read part
> of the docs are a bit unclear.
>
> Say I have code that looks a bit like this - I want to write a
> buffer and
> return the response back to the client (sort of half-synch/half/async
> pattern) - so the client sees a synchronous interface and and I use
> the
> async mechanism underneath.
Hmm, if you really don't have requirement for async - probably it's
better to follow req/resp pattern in blocking manner. But it's up to
you for sure.


> I was thinking something along the lines of:
>
> public Future<ReadResult<Buffer, SocketAddress>> send(Connection
> connection,
> Buffer buffer){
> Future<WriteResult<Buffer, SocketAddress>> writeFuture =
> asyncQueueWriter.write(connection, buffer,
> new CompletionHandlerAdapter<WriteResult<Buffer,SocketAddress>>(){
> @Override
> public void failed(Connection connection, Throwable throwable) {
> try {
> setupConnection(address);
> } catch (Throwable t){
> logger.warn("connection write failed - attempting
> reconnection", t);
> }
> }
> });
> writeFuture.get() // do I need this here?
> return asyncQueueReader.read(connection);
> }
Thinking about your usecase... If I remember the requirement, you need
to send packets simultaneously from different threads, right?
So, IMHO, to make receive part work in proper way - you'll probably
need to call "asyncQueueReader.read(connection);" inside writer's
CompletionHandler like this:

public Future<ReadResult<Buffer, SocketAddress>> send(Connection
connection,
Buffer buffer){
    Future<WriteResult<Buffer, SocketAddress>> writeFuture =
asyncQueueWriter.write(connection, buffer,
                        new CompletionHandlerAdapter<WriteResult<Buffer,SocketAddress>>(){
                                 @Override
                                 public void completed(Connection
connection, WriteResult result) {
----> asyncQueueReader.read(connection); // But additionally
you'll need to provide reader's completion handler here to check the
read status
                                  }

                                @Override
                                public void failed(Connection connection, Throwable throwable) {
                                        try {
                                                setupConnection(address);
                                        } catch (Throwable t){
                                                logger.warn("connection write failed - attempting reconnection",
t);
                                        }
                                }
                });


>
> However, I have a few further questions.
> 1) I am unsure as to whether I have to wait for the future returned
> from the
> write method to complete before calling the read method.
Think this is answered by sample above :)

> 2) If I supply no buffer to the read method does Grizzly manage this
> for me.
> (I seem to get nullpointer in current 2.0 code doing this)
I'll fix this.

> 3) what role does the callbackhandler play in relation to the future
> returned from read- if I register for the handler does the complete
> callback
> happen before the future return - and can I read the response from
> there.
For non-blocking I/O operations Future will be returned immediately.
And then you'll be able to check operation status, using the Future
object. Or/and you can register CompletionHander with I/O operation
and Grizzly will notify it once I/O operation completed or has other
status change.
Yes, you can read response from CompletionHandler.

>
> 4) is the use of the future and the callbackhandler mutually
> exclusive or
> cooperative.
cooperative.

Please note, that response, which may come on asyncQueueReader could
have half of message, or several messages at once.
Currently this could not be resolved with AsyncQueueReader :(

So, what I can propose to you - is to implement write (send) part
using asyncQueueWriter, as you already have.
But receiving side as Filter chain. Where you'll be able to parse
response using StreamReader and notify sender about received response.

Here is example of FilterChain:
https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/samples/framework-samples/src/main/java/org/glassfish/grizzly/samples/filterchain/GIOPParserFilter.java?view=markup

So once your Filter will parse the response message, you need to
figure out which request corresponds to this response - and notify the
sender.

Here is complete Client/Server filterchain example:
https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/samples/framework-samples/src/main/java/org/glassfish/grizzly/samples/filterchain


WBR,
Alexey.



>
>
>
>
> Oleksiy Stashok wrote:
>>
>>> Ok - that makes more sense. So I assume that the transport can
>>> support many
>>> connections to different endpoints and I can use the async writer to
>>> dispatch to all these connections?
>> Absolutely.
>> Transport describes the nature of networking layer (like TCP, UDP),
>> and Connection is a represents unit (like socket).
>>
>> WBR,
>> Alexey.
>>>
>>>
>>> steve
>>>
>>>
>>>
>>>
>>> Oleksiy Stashok wrote:
>>>>
>>>> Hi Steve,
>>>>
>>>>> I am pretty new to Grizzly and I am exploring the use of 2.0 as a
>>>>> client
>>>>> side library.
>>>>>
>>>>> However, I am slightly confused as to how the 2.0 API functions.
>>>>>
>>>>> Is the connection supposed to be for use by a single thread
>>>>> only? -
>>>>> The
>>>>> reason I ask this is the streamwriter that is used to send data
>>>>> has
>>>>> write(Buffer) - which seems ok - but the
>>>>> flush(CompletionHandler) is
>>>>> not
>>>>> part of this call - so if I have multiple threads using the same
>>>>> connection
>>>>> how do I ensure that the order of write/flush is not interleaved
>>>>> unless I am
>>>>> synchronizing these calls myself.
>>>> Actually StreamReader and StreamWriter are not thread safe, so I
>>>> would
>>>> not suggest to use the simult. from several threads.
>>>> Instead of that I'd recommend you to use lower level
>>>> AsyncWriteQueue
>>>> API, which is thread-safe.
>>>>
>>>> Here is example:
>>>> TCPNIOTransport transport = .....;
>>>> Connection connection = .....;
>>>> final MemoryManager mm = transport.getMemoryManager();
>>>> final Writer asyncQueueWriter =
>>>> transport.getAsyncQueueIO().getWriter();
>>>>
>>>> Buffer buffer = MemoryUtils.wrap(mm, "Hello World");
>>>> try {
>>>> asyncQueueWriter.write(connection, buffer);
>>>> } catch (IOException e) {}
>>>>
>>>>
>>>> asyncQueueWriter in this example is thread safe, and you can use it
>>>> simult. from different threads.
>>>>
>>>>> Also, what would be the best approach to use as a reconnection
>>>>> strategy (the
>>>>> transport has an exception handler - but the connection does
>>>>> not) -
>>>>> especially around ability not to lose queued data on a connection
>>>>> that may
>>>>> no longer be active - e.g would I have to drain the queue and
>>>>> reconnect and
>>>>> resubmit manually.
>>>> If you use AsyncWriteQueue - it is possible to set
>>>> CompletionHandler
>>>> there for each Buffer that you send. If error happens - framework
>>>> will
>>>> call CompletionHandler.failed(...) for each Buffer, so you'll be
>>>> able
>>>> to resend those data again.
>>>>
>>>> asyncQueueWriter.write(connection, buffer, new
>>>> CompletionHandlerAdapter() {
>>>> @Override
>>>> public void failed(Connection connection, Throwable
>>>> throwable) {
>>>> resendFailedBuffer(connection, buffer);
>>>> }
>>>> });
>>>>
>>>> If you have any question - please let me know.
>>>>
>>>> WBR,
>>>> Alexey.
>>>>
>>>>>
>>>>>
>>>>> Regards
>>>>> Steve
>>>>>
>>>>>
>>>>> --
>>>>> View this message in context:
>>>>> http://www.nabble.com/Grizzly-2.0-as-a-client-connection-provider-tp22680820p22680820.html
>>>>> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>
>>>>
>>>>
>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/Grizzly-2.0-as-a-client-connection-provider-tp22680820p22689886.html
>>> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>>
>>
>
> --
> View this message in context: http://www.nabble.com/Grizzly-2.0-as-a-client-connection-provider-tp22680820p22755949.html
> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>