You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Steven E. Harris" <se...@panix.com> on 2006/12/27 22:21:11 UTC

Notification of non-blocking write availability

Does MINA offer some callback equivalent of the ACE library's
ACE_Event_Handler::handle_output() function?¹ In ACE, this function
gets called by a Reactor when a socket is available for writing,
meaning that the outbound TCP buffer is drained sufficiently to take
on new write requests without blocking. This doesn't guarantee that
the data will actually be sent out immediately; rather, it just means
that trying to write to the socket won't block.

I'm wondering how one could write a program with MINA that sends out a
lot of data over a socket, but does so in a way that respects flow
control, not sending data while the connection is congested.


Footnotes: 
¹ http://www.dre.vanderbilt.edu/Doxygen/Current/html/ace/classACE__Event__Handler.html#b2597826e388fc1cc34b8879febbd722

-- 
Steven E. Harris

Re: Notification of non-blocking write availability

Posted by "Steven E. Harris" <se...@panix.com>.
Trustin Lee <tr...@gmail.com> writes:

> But you can check the number of buffered messages by calling
> IoSession.getScheduledWrites() or the number of buffered bytes by
> calling IoSession.getScheduledWriteBytes(), so you can stop writing
> additional messages by checking the value whenever you write a
> message.  once a message is flushed out, messageWritten() event is
> invoked, so you can get notified, too.

I see. That's not quite the same thing that ACE (and
java.nio.channels.spi.AbstractSelector) provides.

> It would be best if there's an automated way to control the flow,
> but didn't find what the best way is yet.  You could give us an
> idea.

Well, I do see the java.nio.SelectionKey.OP_WRITE interest operation.¹
That sounds like it's there to detect precisely the same events that
ACE_Event_Handle::handle_output() advises.

I wouldn't expect this OP_WRITE notification to necessarily be visible
at the MINA user level, as MINA is already handling outbound message
queuing and hence insulating the user from the actual pushing of
buffers into the socket.

Take a look at Section 5.5 (pages 16 and 17) of /The Design and Use of
the ACE Reactor/.² There, the authors show how to request OP_WRITE
wakeup/notification if the outbound message queue is not empty, and
how to cancel such notification when the queue is drained.

It's possible that the message queue has messages in it, but the
socket's buffer is sufficiently congested that no more data can be
pushed in. Registering for OP_WRITE notification allows the queue
worker to wait until the socket is ready to accept more data.

I've just started poking through MINA's socket output code. It looks
like some points where OP_WRITE registration/notification could be
relevant are in

  org.apache.mina.transport.socket.nio.SocketFilterChain.doWrite()

and

  org.apache.mina.transport.socket.nio.SocketIoProcessor.process()

But I kept looking and just found SocketIoProcessor.doFlush(), which
registers for the OP_WRITE interest when its attempt to write an
entire buffer falls short. Similar behavior is in
SocketIoProcessor.doUpdateTrafficMask().

Well, I'll stop there. It looks like a lot of what I'm describing is
already built into MINA. It's just hidden nicely from the user,
perhaps as it should be.


Footnotes: 
¹ http://java.sun.com/javase/6/docs/api/java/nio/channels/SelectionKey.html#OP_WRITE
² http://www.cse.wustl.edu/~doc/pspdfs/reactor-rules.pdf

-- 
Steven E. Harris

Re: Notification of non-blocking write availability

Posted by Trustin Lee <tr...@gmail.com>.
Hi Steven,

On 12/28/06, Steven E. Harris <se...@panix.com> wrote:
>
> Does MINA offer some callback equivalent of the ACE library's
> ACE_Event_Handler::handle_output() function?¹ In ACE, this function
> gets called by a Reactor when a socket is available for writing,
> meaning that the outbound TCP buffer is drained sufficiently to take
> on new write requests without blocking. This doesn't guarantee that
> the data will actually be sent out immediately; rather, it just means
> that trying to write to the socket won't block.


No.  But you can check the number of buffered messages by calling
IoSession.getScheduledWrites() or the number of buffered bytes by calling
IoSession.getScheduledWriteBytes(), so you can stop writing additional
messages by checking the value whenever you write a message.  once a message
is flushed out, messageWritten() event is invoked, so you can get notified,
too.

It would be best if there's an automated way to control the flow, but didn't
find what the best way is yet.  You could give us an idea.

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6