chuckremes / ffi-rzmq

FFI bindings for ZeroMQ so the library can be used under JRuby and other FFI-compliant ruby runtimes
242 stars 62 forks source link

hanging the whole process #116

Closed qqshfox closed 9 years ago

qqshfox commented 9 years ago

zmq newbie here. I'm trying to play zmq with sinatra.

require 'sinatra/base'
require 'ffi-rzmq'

class Server
  def initialize
    ctx = ZMQ::Context.new
    @s  = ctx.socket ZMQ::REP

    ## if replace above codes with following codes, it won't hang any more
    #@ctx = ZMQ::Context.new
    #@s  = @ctx.socket ZMQ::REP

    p @s
  end
end

SERVER = Server.new

class App < Sinatra::Application
  run! if app_file == $0
end

it could print the @s, then hanging on there:

#<ZMQ::Socket:0x007fb2da903190 @receiver_klass=ZMQ::Message, @socket=#<FFI::Pointer address=0x007fb2d90fba00>, @name="REP", @int_cache=nil, @longlong_cache=nil, @more_parts_array=[], @option_lookup=[nil, nil, nil, nil, 1, 2, 2, 2, 0, 0, nil, 0, 0, 1, 0, 0, 0, 0, 0, 0, nil, 0, 1, 0, 0, 0, nil, 0, 0, nil, nil, 0, 2, 0, 0, 0, 0, 0, 0, 0, nil, nil, 0, 0, 0, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 2]>

after ctrl-c:

^C[2014-11-20 14:48:46] INFO  WEBrick 1.3.1
[2014-11-20 14:48:46] INFO  ruby 2.1.4 (2014-10-27) [x86_64-darwin14.0]
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from WEBrick
[2014-11-20 14:48:46] INFO  WEBrick::HTTPServer#start: pid=87106 port=4567

Is this intentional in ffi-rzmq or even in libzmq? Or it just might be a bug that the ruby object ctx was GCed in that situation?

Thanks, Hanfei

PS.

$ ruby -v
ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-darwin14.0]
$ gem list rzmq
ffi-rzmq (2.0.1)
ffi-rzmq-core (1.0.3)
$ brew info zmq
zeromq: stable 4.0.5 (bottled), HEAD
http://www.zeromq.org/
/usr/local/Cellar/zeromq/4.0.5_2 (64 files, 2.8M) *
  Poured from bottle
From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/zeromq.rb
schmurfy commented 9 years ago

Some things you can try (just to check where the problem comes from):

I don't see why it might hangs at first glance.

qqshfox commented 9 years ago

I've already tried.

keep a reference to the context (@ctx instead of ctx)

As I mentioned in the comment, this works.

remove the "p @s"

It won't help.

schmurfy commented 9 years ago

oops, my bad I missed (or more misread) the comment in your original post xD I am pretty sure the issue is in ffi-rzmq and not in libzmq, I have not dealt directly with ffi for quite some time now but I remember strange bugs when a reference is not kept to each objects.

I think what happens is the context is destroyed when it goes out of scope and since a socket if opened libzmq it will wait on it, most of the issues I had at the time similar to this were only reproduced in examples/tests since in real use case you will often do thing differently, in this case you should keep a reference to the context anyway.

I don't have the code but a way to solve it would be for each socket to keep a reference to the ruby object representing the context.

chuckremes commented 9 years ago

@qqshfox The information provided by @schmurfy is correct. If you do not keep the 'ctx' around, the garbage collector will collect it and try to terminate the context. Any open sockets will then start to return ETERM. Please read the man pages and documentation for zeromq over at zeromq.org.

The easiest fix for the code above is to change 'ctx' to '@ctx' so it is stored in an instance variable for your class.