This is a reminder for a known problem: if EventMachine reactor is started before main process forks (a very common case with Unicorn and Passenger), EventMachine reactor becomes effectively disfunctional: EventMachine.reactor_running? returns true but no data is sent, EventMachine.stop has no effect and to completely reset reactor state one has to violate incapsulation by using Object#instance_variable_set.
We need to detect forks, possibly in EM.run if Process.pid has changed.
This usually causes problems using AMQP with forking http servers like unicorn and passenger. I initially wrote AMQP.fork as a workaround. Currently a hack is required:
This should work, can you verify?
diff --git a/lib/eventmachine.rb b/lib/eventmachine.rb
index 6e0fbf3..b2044e7 100644
@@ -154,9 +154,15 @@ module EventMachine
# which throws something inside of #run. Without the ensure, the second test
# will start without release_machine being called and will immediately throw
+ if reactor_running? and @reactor_pid != Process.pid
+ # Reactor was started in a different parent, meaning we have forked.
+ # Clean up reactor state so a new reactor boots up in this child.
+ @reactor_running = false
+ # Add tail call block
tail and @tails.unshift(tail)
@@ -169,6 +175,7 @@ module EventMachine
@next_tick_queue ||= 
@tails ||= 
+ @reactor_pid = Process.pid
@reactor_running = true
(b = blk || block) and add_timer(0, b)
Thank you, I will take a look in the next day or two.