Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RethinkDB::Binary causes hang on jRuby #3795

Closed
jhstatewide opened this issue Feb 18, 2015 · 21 comments
Closed

RethinkDB::Binary causes hang on jRuby #3795

jhstatewide opened this issue Feb 18, 2015 · 21 comments
Labels
Milestone

Comments

@jhstatewide
Copy link

The following script causes a client hang on JRuby:

https://gist.github.com/jhstatewide/e214d9d567b82f0d29ef

jruby 1.7.13 (1.9.3p392) 2014-06-24 43f133c on Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17 [linux-amd64]

works fine on MRI 1.9.1

@deontologician
Copy link
Contributor

This was also against server version 1.15.2~0trusty

@danielmewes danielmewes added this to the 1.16.x milestone Feb 18, 2015
@danielmewes
Copy link
Member

@mlucy can you take a look at this?

@mlucy
Copy link
Member

mlucy commented Feb 18, 2015

@danielmewes -- will do.

@jhstatewide
Copy link
Author

https://gist.github.com/jhstatewide/df4842f63efb20d7eb3e Here is a stack trace from the hanging program. I generated this with "jstack", hopefully it is of some use.

@mlucy
Copy link
Member

mlucy commented Feb 18, 2015

@jhstatewide -- does this happen every time?

@jhstatewide
Copy link
Author

@mlucy, yes, 100% reproducible with this script

@mlucy
Copy link
Member

mlucy commented Feb 18, 2015

Alright, planning to work on this next once my current changes are in. It's probably a result of JRuby having real threads and us not testing the multithreaded part of our driver in anything except CRuby.

@larkost -- once this is fixed, would it be possible to add JRuby to the list of Ruby versions we test with?

@jhstatewide
Copy link
Author

I have further information... I generated random strings at increasing lengths... the following script works fine until the document reaches ~60k bytes...

https://gist.github.com/jhstatewide/70ea290678ac2eda4ce1

It also works great on MRI... 200k+ and counting

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

Haven't investigated it, but it could be the query is filling up the TCP send buffer which the driver may not be handling correctly.

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

If this is the problem, it may be that changing the @socket.write(packet) in net.rb to @socket.sendmsg(packet) would solve it. That would block the query thread until all the data has made it into the TCP send buffer.

@jhstatewide
Copy link
Author

@Tryneus sendmsg is not implemented on JRuby but I can confirm that the hang is on that @socket.write

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

I reproduced this on newton using JRuby 1.17.19, and it appears that the @socket.write call hangs inside JRuby. The server read out the beginning of the query and is waiting for more, but the main thread of execution in the client doesn't resume sending it.

This would likely correspond to this area of the stack trace from @jhstatewide:

"main" #1 prio=5 os_prio=0 tid=0x00007ffb9c00a000 nid=0x15ae waiting for monitor entry [0x00007ffba38c2000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.jruby.RubyThread.select(RubyThread.java:1264)
    - waiting to lock <0x00000000f60247d0> (a java.lang.Object)
    at org.jruby.RubyThread.select(RubyThread.java:1256)
    at org.jruby.RubyIO.waitWritable(RubyIO.java:1436)
    at org.jruby.RubyIO.fwrite(RubyIO.java:1500)
    at org.jruby.RubyIO.write(RubyIO.java:1410)
    at org.jruby.RubyIO$INVOKER$i$1$0$write.call(RubyIO$INVOKER$i$1$0$write.gen)
...

Perhaps the JRuby waitWritable implementation is broken. Trying to find if there's an alternative way to do this.

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

I wouldn't recommend using this as the solution, but on newton, changing the @socket.write to @socket.syswrite seems to work.

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

Ok, my last comment was a little misleading as I hadn't had a chance to fully test it. At this point, I'm willing to accept this as a solution (up in code review 2630).

The new Connection::send function is:

def send packet
  written = 0
  while written < packet.length
    written += @socket.syswrite(packet.slice(written, packet.length))
  end
end

It seems that JRuby's IO::write has a hanging problem with waiting on the socket to become writable again. If we use JRuby's IO::syswrite, it will not hang, but it may return partial writes. MRI does not appear to have either of these problems.

Tested with extremely large rows, resulting in many partial writes on JRuby, everything seems to be in working order.

Tested with JRuby 1.7.19 (built from source) and Ruby 2.0.0.

@jhstatewide
Copy link
Author

@Tryneus: I can confirm your findings. Both of my test cases now pass with your updates to net.rb. Thanks very much for the fast response!

@deontologician
Copy link
Contributor

👍

@Tryneus
Copy link
Member

Tryneus commented Feb 19, 2015

Fix has been approved and merged to next in commit 1f5dce2, and cherry-picked into v1.16.x in commit 5b6e928. Will be in release 1.16.3 (or earlier if we do a ruby driver release for this).

Thanks for reporting this, @jhstatewide, glad we could get to the root of it!

@Tryneus Tryneus closed this as completed Feb 19, 2015
@danielmewes
Copy link
Member

@AtnNn Can we push out an update of just the Ruby driver?

@AtnNn
Copy link
Member

AtnNn commented Feb 19, 2015

I'll do that now.

@AtnNn
Copy link
Member

AtnNn commented Feb 19, 2015

The new version of the ruby driver, 1.16.0.1, has ben released and includes this fix.

@danielmewes
Copy link
Member

Cool, thank you @AtnNn

@AtnNn AtnNn modified the milestones: 1.16.x, 2.0 Mar 17, 2015
@AtnNn AtnNn modified the milestones: 2.0, 1.16.x, 1.16.3 Mar 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants