There are at least two distinct aspects that we need to discuss when talking NIO
optimization.
First there is the fact that a non-blocking IO implementation, complete with readiness
selection, allows a single thread (or a precisely limited number of threads) to
efficiently do what in a thread-per-connection model would take a number of threads equal
with the number of connections. This approach a) avoids thread context switching that
becomes toxic after the number of threads in use reaches a certain threshold and b)
prevents using the thread scheduler as a substitute for a readiness selection mechanism
(threads that suddenly get something to read, or write, are un-blocked by the scheduler,
which acts as a "de facto" readiness detector).
The second advantage of using NIO is the fact that, thanks to direct buffers, JVM client
code can read and write directly physical memory that is also directly accessed by device
drivers (the network driver or the DMA subsystem). The java code has no idea that it
actually doesn't write JVM heap, but physical memory that is also mapped in the kernel
space, so it can be directly accessed by the said devices. Regardless of how it is
actually done, the net benefit is avoiding copying bytes over. However, one must keep in
mind that direct buffers are much more heavier entities than simple byte arrays, they take
a lot more time to allocate, and they are not subject to JVM memory management and garbage
collection.
So, the thing I want to point out is that these two different aspects are ORTHOGONAL. I
can pass a byte[] to a NIO implementation, and the implementation can make sure the buffer
is completely read (or written) the same way it would make sure a ByteBuffer is completely
read and written (and yes, that's true, by internally creating a direct ByteBuffer and
copying bytes over).
So, I agree that there is an efficiency problem with using byte[] instead of direct
ByteBuffers, but saying that an interface that use byte[] cannot inherently work with a
NIO runtime is just wrong. A byte[] has nothing to do with non-blocking-ness per se.
Tim wrote :
| This is what non blocking is all about. A blocking implementation would block until
all the bytes had been written. This preventing the thread neing used for anything else
while the blocking is occurring.
|
No, this is not what non blocking is all about. There are two different (and orthogonal)
aspects: non-blocking behavior + readiness selection AND direct buffers. You can avoid
using direct buffers if you want to, and still get non-blocking behavior at the
"lower" level of your framework. In the end, you want to achieve separation
between your client code and the transport.
Tim wrote :
| This also means it's going to be up to the application to piece together requests
and responses.
|
No.
Let's walk through a simple example. Let's say that you want to send a message
acknowledgment from the client to the server, saying that message with id = 77 has been
successfully processed by the client code.
With the API that I am proposing, you can do this:
You allocate a byte[] of five bytes. The first byte is the operation code. Let's
assume for the sake of the example that the acknowledgment operation code is 11. The rest
of four bytes contain the message id. So you end with a { 0x0B, 0x00, 0x00, 0x00, 0x4D }
byte array, that you just hand over to "remoting" (or whatever superstructure
based on NIO you want to use). The "remoting" module would wrap the byte[] in a
ByteBuffer and passes it to a SocketChannel, writing it in a non-blocking manner on the
channel using the thread it manages.
Your client thread returns immediately, and your { 0x0B, 0x00, 0x00, 0x00, 0x4D }
acknowledgment will be, eventually, sent on the wire, by the "remoting" layer
thread.
So you this way you achive a separation between your "client" thread, that just
hands over the bytes, and the "remoting" thread that actually performs the
non-blocking operations on the channel. This is as "SEDA" as you can get.
Tim wrote :
| It seems to me that our biggest issue is getting an implementation up and running. So
far we haven't even got the interface sorted.
|
We will decide on a solution at the end of the remoting meeting that will take place this
week. The solution I propose is one of the possible outcomes. Using an external framework
it's another. Nothing is a priori overruled.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3980596#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...