[muscle] Re: Patch for supporting NIO in Java client

  • From: Lior Okman <lior.okman@xxxxxxxxxxxxxxxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Sun, 29 Jan 2006 00:51:13 +0200

Jeremy Friesner wrote:

>Hi Lior,
> 
>  
>
>>MessageTransceiver2 is exactly the same as MessageTransceiver, except
>>that it uses NIO instead of the old I/O. The issue is that nio and old
>>IO don't mix well, so I thought it would be better to separate the two
>>driving classes completely. It is possible to reuse some parts of the
>>identical code. I'll probably do it later on, when I have more time on
>>my hands.
>>    
>>
>
>I see.
> 
>  
>
>>In addition, it is possible to compile the Java client with a 1.4.0 or
>>higher version of the Java compiler, in such a way as to allow older
>>JVMs to use the generated class files. This would work, as long as the
>>NIO code is not used at runtime in an older JRE.
>>    
>>
>
>That is what I'm most concerned about -- someone with an older
>web browser not being able to run an applet because web browser's
>older JVM can't handle the new code.  (Having an applet that only
>works on a few new browsers would defeat the "write once,
>run anywhere" characteristic that makes Java attractive)
>
>  
>
I think all the Java browser plugins circa 2006 can handle Java 1.4
compatible code. It's not the web-browser version that is relevant, it's
the Java plugin installed. Java 1.4 is so old by now, it's hard not to
find. Bacwards compatability is important, but JDK 1.4 has been here and
gone already, and supporting JDK 1.3 and older might not still be required.

>>lior:~/java/muscle/java$ mkdir bin
>>lior:~/java/muscle/java$ javac -d bin -source 1.3 -target 1.3  `find .
>>-name \*.java`
>>
>>The class files generated here will be usable for jdk version 1.3 and
>>up, as long as you don't use unsupported things like NIO in the 1.3 runtime.
>>    
>>
>
>Interesting... so it would be up to the developer to check the host's JVM 
>version
>at run time, and use MessageTransceiverThread or MessageTransceiverThread2
>as appropriate.  Perhaps we could include a factory method to do this
>automatically?
>
>  
>
This is indeed doable - for example like this:

try {
    Class.forName("java.nio.ByteBuffer");
    // Use new I/O code.
}
catch (ClassNotFoundException cnfe) {
    // Use old I/O code.
}

However, I don't think it's needed. Most people nowadays work with JDK
1.4.0 or higher, and they would be able to use the new code.

Are people using MUSCLE in a web browser? I mostly see people using Java
in enterprise environments, and I almost never see people actually use
applets. I'm currently using the Java MUSCLE client for a system that
spans Windows, Linux and Solaris hosts, but it's in a standalone Java 
environment, very very far from browsers.

>The question would be, is the efficiency increase obtained by having NIO
>support worth the extra versioning complexity?  Or is either implementation 
>going
>to be effectively bound by network bandwidth anyway, in which case one
>might as well always use the older, more portable code?
>
>  
>
NIO allows code to be written that is more efficient and that can
theoritically scale better than the InputStream/OutputStream classes
that were available before JDK 1.4.0 . I think that NIO is the way to go
for Java networking code. Right now I'm using the MUSCLE Java client in
an environment that has JDK 1.4.2 available, and I think some of my
performance problems can be traced back to the MUSCLE Java
implementation. I'm seeing a lot of time spent in the LEDataOutputStream
class, so this patch is the start of my attempts to "make it better".

In my first profiling comparision between the NIO and old I/O code,
sending 1200 Messages takes 30% more time with old I/O than it does with
nio.
In this case, the MUSCLE server and both clients are all on the same
machine, so network bandwidth isn't an issue, and both clients are Java
clients, in both cases running under the same profiler.

Benefits of NIO in this case:

1. Compression is better, since an entire message can be compressed at
once, instead of calling the compression for each item written into the
network.
2. When actually accessing the network, an entire ByteBuffer is passed
to the OS at once, so the OS can send more data at once. This passes the
burden of utilizing the network to the OS, instead of leaving it in the
hands of the Java client, and waiting for "flush()" calls.

I think, that based on this very early result, the NIO patch is worth it.

Lior

>Jeremy
>
>
>
>  
>


Other related posts: