users@grizzly.java.net

use AsyncQueueWriter

From: Amy Kang <Amy.Kang_at_Sun.COM>
Date: Mon, 16 Mar 2009 17:35:37 -0700

Hi,

I have a server that needs to write data to client asynchronously
after the client sends a request to register its interest for certain type
of messages. The server allocates a thread (non-Grizzly thread) to
do that using AsyncQueueWriter which is obtained from the SelectorHandler
of the client request's Context,

ctx.getSelectorHandler()

and later when there is a message for the client, the server will do
following
(see below code example).

This works fine for single client. When multiple clients run at same
time, the
following code often throws NPE or IOException. Is the following code
using
Grizzly AsyncQueueWriter correctly ? I'm using Grizzly 1.9.8.

java.io.IOException
        at
com.sun.grizzly.async.AbstractAsyncQueueWriter.write(AbstractAsyncQueueWriter.java:265)
        at
com.sun.grizzly.async.TCPAsyncQueueWriter.write(TCPAsyncQueueWriter.java:77)
        at
com.sun.grizzly.async.AbstractAsyncQueueWriter.write(AbstractAsyncQueueWriter.java:140)
        at
com.sun.grizzly.async.AbstractAsyncQueueWriter.write(AbstractAsyncQueueWriter.java:130)
        at
com.sun.grizzly.async.AbstractAsyncQueueWriter.write(AbstractAsyncQueueWriter.java:79)
        at
com.sun.messaging.bridge.service.stomp.AsyncStompOutputHandler.sendToClient(AsyncStompOutputHandler.java:75)
        at
com.sun.messaging.bridge.service.stomp.StompTransactedSession.run(StompTransactedSession.java:672)
        at java.lang.Thread.run(Thread.java:595)
--------------------

java.lang.NullPointerException
        at com.sun.grizzly.NIOContext$AsyncQueueWritableContextWrapper.writeToAsyncQueue(NIOContext.java:671)
        at com.sun.messaging.bridge.service.stomp.StompProtocolFilter.sendToClient(StompProtocolFilter.java:150)
        at com.sun.messaging.bridge.service.stomp.StompProtocolHandler.onCONNECT(StompProtocolHandler.java:129)
        at com.sun.messaging.bridge.service.stomp.StompProtocolFilter.execute(StompProtocolFilter.java:92)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:136)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:103)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:89)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:67)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
-----------------------------------------------
        at java.lang.Thread.run(Thread.java:619)

async write data to client:

 try {

        ByteBuffer bb = msg.marshall();
        if (_sslengine == null) {
            _selectorhandler.getAsyncQueueWriter().write(_selectionkey, bb);
        } else {
           int osize = Math.max(8192,
_sslengine.getSession().getPacketBufferSize());
           ByteBuffer outputBB = ByteBuffer.allocate(osize);
           outputBB.position(0);

           SelectableChannel sc = _selectionkey.channel();
           synchronized(sc) {

           SSLOutputWriter.flushChannel(sc, bb, outputBB, _sslengine);

           }
        }

        } catch (java.nio.channels.ClosedChannelException e) {
            _logger.log(Level.WARNING, "Sending message to client
failed: "+e.toString());
            _sph.close(true);
            throw e;
        }

-------------
Thanks,
amy