[jboss-dev-forums] [Design of Messaging on JBoss (Messaging/JBoss)] - Re: Messaging and Remoting
ovidiu.feodorov@jboss.com
do-not-reply at jboss.com
Tue Oct 24 23:11:09 EDT 2006
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#3980596
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3980596
More information about the jboss-dev-forums
mailing list