stompgem / stomp

A ruby gem for sending and receiving messages from a Stomp protocol compliant message queue. Includes: failover logic, ssl support.
http://stomp.github.com
Apache License 2.0
152 stars 80 forks source link

Stomp::Client#close not safe to call within a signal handler #79

Closed rtyler closed 10 years ago

rtyler commented 10 years ago

This issue was reported by a coworker, who was seeing the following exception:

/Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stomp-1.2.16/lib/connection/utils.rb:109:in `synchronize': can't be called from trap context (ThreadError)
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stomp-1.2.16/lib/connection/utils.rb:109:in `socket'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stomp-1.2.16/lib/connection/netio.rb:124:in `transmit'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stomp-1.2.16/lib/stomp/connection.rb:393:in `disconnect'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stomp-1.2.16/lib/stomp/client.rb:233:in `close'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stapfen-1.4.2/lib/stapfen/worker.rb:140:in `exit_cleanly'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stapfen-1.4.2/lib/stapfen/worker.rb:70:in `block (2 levels) in handle_signals'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stapfen-1.4.2/lib/stapfen/worker.rb:69:in `each'
    from /Users/yranadive/.rvm/gems/ruby-2.0.0-p195/gems/stapfen-1.4.2/lib/stapfen/worker.rb:69:in `block in handle_signals'
    from test_consumer.rb:34:in `call'
    from test_consumer.rb:34:in `join'
    from test_consumer.rb:34:in `block in run_workers'
    from test_consumer.rb:33:in `each'
    from test_consumer.rb:33:in `run_workers'
    from test_consumer.rb:64:in `<main>'

Basically, if a Stomp::Client is instructued to close in a signal handler (SIGINT/SIGTERM) the following exception can be raised, and won't cleanly terminate the Client

PaulGale commented 10 years ago

Can you post your test code? I have exit handling working without a problem in JRuby and MRI.

gmallard commented 10 years ago

Relevant:

https://www.ruby-forum.com/topic/4411227

https://www.ruby-forum.com/topic/4416641

gmallard commented 10 years ago

Status: Closed Ref: Core Ruby 2+ functionality, not a gem bug.

The Ruby team seems unlikely to revert this behavior to 1.x levels. Additional discussions:

http://bugs.ruby-lang.org/issues/7917 http://bugs.ruby-lang.org/issues/7648 https://github.com/celluloid/celluloid-io/issues/66

One suggested work around for simplistic cases:

client = Stomp::Client.new(....)
#
# Additional logic ....
#
Signal.trap(:INT) { # Alternatively Kernel.trap
    puts "Stopping... 1"
    ct = Thread.new do # close in a different thread
      client.close
    end
    ct.join
    puts "Stopping... 2"
    exit 0 # Perhaps.
}