|
|
|
sorry - the workaround should read
Also seeing this with Java5 on Mac OS X 10.4.9, using JRuby 0.9.8. Lemme know if I can help test a fix!
The request hangs here, in org.jruby.runtime.builtin.meta.IOMetaClass.select_static (lines 265-269):
if(args.length > 3) { selector.select(timeout); } else { selector.select(); } The selector.select call is made with a timeout value of 0. I recall seeing something like this in a project I worked on a few years ago, but that was in C under Solaris. As I recall, the solution had to do with retrying after EAGAIN/EWOULDBLOCK was received, but I'm not sure how that maps into NIO (which I haven't worked with). Meanwhile, I've been using Terry Woloszyn's solution, as follows: require 'drb'
# temporary hack to work around jruby-drb problem
module DRb
class DRbTCPSocket
def alive?
return false unless @socket
if IO.select([@socket], nil, nil, 0.05)
close
return false
end
true
end
end #DRbTCPSocket
end #DRb
I took a look at this and determined the following:
(on another note, it looks like IOHandlerNio won't reliably let you 'ungotc' a zero byte because there are several checks for 'ungotc>0' which should be 'ungotc>=0')
I made some nasty hacks to verify that fixing the above resolves the problem with drb, but I suspect it's best left to the people who properly understand the JRuby IO infrastructure to make the proper interfaces. Hope that helps! I've attached a patch containing a variation on the nasty hacks alluded to in my earlier comment today.
IOHandler.hasPendingBuffered() perhaps has to be implemented correctly for other subclasses of IOHandler (currently only IOHandlerNio). I've not tested this very thoroughly, so it may break some other things. It does seem to fix the test case described in this issue. For ruby 1.8.5 (2007-04-23 rev 3489) [i386-jruby0.9.9-pre]
, the IOMetaClass.java has been folded into RubyIO. I recreated the original bufferedIoSelect patch for this release. Just "patch -p1 <..." to apply to current trunk. BTW - nice job on the threading etc.! This release appears to have cured both a hanging issue, as well as InterruptedException issue I was having with concurrent access to DRb objects. I will continue testing, but this is real progress for DRb! Thanks! here is the patch as desribed previously, updating the original patch for BufferedIoSelect. The original caveats still apply, but it seems to work for my test cases.
I applied the later patch for the most part. Drb works much better with this...
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
If a timeout is added, even as little as 0.05, then the call is retried twice, and proceeds normally, continuing to use the same connection.
e.g. IO.select(socket, nil, nil, 0.05)
Probably a good reason why timeout was 0 to begin with, but this is working as a workaround in the test cases.
Threading issue? And if we leave the timeout in place, will it come back to bite us somewhere else?