celluloid / celluloid-io

UNMAINTAINED: See celluloid/celluloid#779 - Evented sockets for Celluloid actors
https://celluloid.io
MIT License
879 stars 93 forks source link

C::IO::TCPSocket.new dies with IO::EAGAINWaitReadable on JRuby v9.0.3.0. #156

Closed clonezone closed 8 years ago

clonezone commented 8 years ago

The following works with celluloid-io 0.17.2 on JRuby v9.0.1.0:

@socket = Celluloid::IO::TCPSocket.new host, port

on JRuby v9.0.3.0, I'm getting

SocketError: (IO::EAGAINWaitReadable) recvfrom(2) would block
    org/jruby/ext/socket/RubyUDPSocket.java:220:in `recvfrom_nonblock'
    org/jruby/ext/socket/RubyUDPSocket.java:227:in `recvfrom_nonblock'
    /install/path/gems/celluloid-io-0.17.2/lib/celluloid/io/udp_socket.rb:22:in `recvfrom'
    /install/path/gems/celluloid-io-0.17.2/lib/celluloid/io/dns_resolver.rb:45:in `resolve'
    /install/path/gems/celluloid-io-0.17.2/lib/celluloid/io/tcp_socket.rb:63:in `initialize'
ioquatix commented 8 years ago

I've seen this issue before.. Look at TCPSocket#connect for details.

clonezone commented 8 years ago

No.

  1. The whole point of Celluloid:IO::TCPSocket is to not have to deal with doing non-blocking I/O yourself.
  2. Did you look at the stack trace? The problem is not with establishing the TCP connection itself. The problem lies with Celluloid's DNS lookup prior to creating the TCP connection.
headius commented 8 years ago

I don't know of anything in JRuby's UDPSocket that would have changed between 9.0.1 and 9.0.3 so this is a bit of a surprise. I assume it works fine on MRI?

Asmod4n commented 8 years ago

looks like https://github.com/celluloid/celluloid-io/blob/master/lib/celluloid/io/dns_resolver.rb#L32 isn't a Celluloid::IO::UDPSocket ? If it would be such a socket it shouldn't throw EAGAIN

tarcieri commented 8 years ago

@Asmod4n it's in the Celluloid::IO::UDPSocket namespace, so it is. See also the stack trace..

If it would be such a socket it shouldn't throw EAGAIN

More like the other way around: We wouldn't see this error if it were a standard library ::UDPSocket, because Celluloid::IO::DNSResolver is making a blocking #recvfrom call.

The confusing bit is why the exception isn't being caught here:

https://github.com/celluloid/celluloid-io/blob/master/lib/celluloid/io/udp_socket.rb#L27

tarcieri commented 8 years ago

Looking at the stack trace, it seems a SocketError is actually what's getting raised, not a IO::EAGAINWaitReadable

headius commented 8 years ago

Can someone summarize the issue and report a JRuby bug? I'm confused what the proper behavior is and what we're not doing right at this point.

tarcieri commented 8 years ago

@headius hard to tell from that stack trace, but it seems like it's raising a SocketError instead of a IO::EAGAINWaitReadable?

HoneyryderChuck commented 8 years ago

Having the same problem here with jruby 9.0.4.0. @tarcieri, I think that in https://github.com/celluloid/celluloid-io/blob/master/lib/celluloid/io/udp_socket.rb#L27 the IO::EAGAINWaitReadable should be rescued as well (I did a quick patch locally and seems to have worked). My question would be, according to ruby defined behaviour, when is IO::EAGAINWaitReadable thrown instead of IO::WaitReadable (the expected exception, is seems).

tarcieri commented 8 years ago

@TiagoCardoso1983 no:

irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> IO::EAGAINWaitReadable
NameError: uninitialized constant IO::EAGAINWaitReadable
2.2.3 :001 > IO::EAGAINWaitReadable.ancestors
 => [IO::EAGAINWaitReadable, IO::WaitReadable, Errno::EAGAIN, SystemCallError, StandardError, Exception, Object, Kernel, BasicObject]

^^^ note IO::WaitReadable is an ancestor of IO::EAGAINWaitReadable

The original problem is something is throwing a SocketError

HoneyryderChuck commented 8 years ago

@tarcieri , indeed it seems something with jruby.

clonezone commented 8 years ago

In my testing, https://github.com/jruby/jruby/issues/3520 has resolved this issue. I would say that this issue can be closed.

For future reference, JRuby v9.0.3.0 and v9.0.4.0 should be considered incompatible with Celluloid IO, but v9.0.5.0 appears to be fine.