jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • JRuby
  • JRUBY-3017

DRb "premature header" error on JRuby client

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.1.4
  • Fix Version/s: JRuby 1.2
  • Component/s: Core Classes/Modules
  • Labels:
    None
  • Environment:
    Mac 10.5.4
    Java 5 & 6
    JRuby 1.0.3 & 1.1.4
    MRI 1.8.6

Description

When I run a DRb server with JRuby 1.1.4 and a DRb client in either JRuby 1.1.4, JRuby 1.0.3, or MRI 1.8.6, I get the following error about half the time....

(druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:571:in `load': premature header (DRb::DRbConnError)
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:612:in `recv_request'
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:912:in `recv_request'
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:1523:in `init_with_client'
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:1535:in `setup_message'
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:1487:in `perform'
	from (druby://localhost:9000) /Users/redsquirrel/Projects/jruby-1.1.4/lib/ruby/1.8/drb/drb.rb:1582:in `main_loop'
	from (druby://localhost:9000) :1:in `accept'
	from :1

When I run the server in anything other than JRuby 1.1.4, everything works great. Here is the code.

server.rb
require 'drb' 
class Server 
  def hello(*args)
    p args
    "success"
  end
end 
DRb.start_service('druby://localhost:9000', Server.new) 
DRb.thread.join
client.rb
require 'drb' 
obj = DRbObject.new(nil, 'druby://localhost:9000') 
200.times { puts obj.hello({:foo => "bar"}) }
  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Text File
    make_selects_restore_blocking_mode.patch
    11/Feb/09 3:34 AM
    17 kB
    Charles Oliver Nutter

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Charles Oliver Nutter added a comment - 03/Oct/08 9:16 AM

Thanks for the simple examples. I think this has been reported before, but I haven't searched bugs. At any rate, it would be nice to squash this one finally.

Show
Charles Oliver Nutter added a comment - 03/Oct/08 9:16 AM Thanks for the simple examples. I think this has been reported before, but I haven't searched bugs. At any rate, it would be nice to squash this one finally.
Hide
Permalink
Charles Oliver Nutter added a comment - 11/Feb/09 3:34 AM

Ok, I've found the source of the problem. It turns out that we're never properly setting blocking state back into the thread after a select. And this is happening in many places in the code. The one directly related to this failure appears to be in the impl of IO::select. We don't ever actually save the old blocking state, and as a result we don't actually restore it after the select is complete. This causes the socket to remain non-blocking, which causes it to return "" on eof rather than block waiting for data.

The attached patch fixes all places I could find where we configure blocking and don't set it back to what it was previously. It also draws attention to the numerous ways in which we select, all slightly different, that could all probably be combined and certainly could be cleaned up. With this patch, the provided Drb scripts work the same under JRuby and Ruby.

It's a very good find...I always wondered if we were incorrectly handling blocking modes. Now I know.

I will continue working on this patch in the morning, to clean it up and try to reduce select logic from the many places it exists now.

Show
Charles Oliver Nutter added a comment - 11/Feb/09 3:34 AM Ok, I've found the source of the problem. It turns out that we're never properly setting blocking state back into the thread after a select. And this is happening in many places in the code. The one directly related to this failure appears to be in the impl of IO::select. We don't ever actually save the old blocking state, and as a result we don't actually restore it after the select is complete. This causes the socket to remain non-blocking, which causes it to return "" on eof rather than block waiting for data. The attached patch fixes all places I could find where we configure blocking and don't set it back to what it was previously. It also draws attention to the numerous ways in which we select, all slightly different, that could all probably be combined and certainly could be cleaned up. With this patch, the provided Drb scripts work the same under JRuby and Ruby. It's a very good find...I always wondered if we were incorrectly handling blocking modes. Now I know. I will continue working on this patch in the morning, to clean it up and try to reduce select logic from the many places it exists now.
Hide
Permalink
Charles Oliver Nutter added a comment - 11/Feb/09 3:05 PM

I've fixed this but I'm not sure how best to test it. Basically the problem was that IO.select was not restoring blocking status to the underlying channel. Since in JRuby we do allow blocking IO to just be normal blocking IO, this caused problems with read calls against an eof stream returning "" instead of blocking. The fix is not particularly pretty...I added another map of IO objects to blocking status, and I use that to restore statuses at the end of the select. But it should work well enough for now, and we'll look at doing a sweep of all select logic in JRuby soon (hopefully for 1.2).

If you can come up with some tests for this case or for select behavior, it would be a big help.

Show
Charles Oliver Nutter added a comment - 11/Feb/09 3:05 PM I've fixed this but I'm not sure how best to test it. Basically the problem was that IO.select was not restoring blocking status to the underlying channel. Since in JRuby we do allow blocking IO to just be normal blocking IO, this caused problems with read calls against an eof stream returning "" instead of blocking. The fix is not particularly pretty...I added another map of IO objects to blocking status, and I use that to restore statuses at the end of the select. But it should work well enough for now, and we'll look at doing a sweep of all select logic in JRuby soon (hopefully for 1.2). If you can come up with some tests for this case or for select behavior, it would be a big help.

People

  • Assignee:
    Charles Oliver Nutter
    Reporter:
    Dave Hoover
Vote (0)
Watch (0)

Dates

  • Created:
    26/Sep/08 9:25 AM
    Updated:
    21/Mar/09 1:14 PM
    Resolved:
    11/Feb/09 3:05 PM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.