Prevent race condition when launching EventMachine reactor

reactor_running? will be true just after the thread enters
EventMachine.run; reactor_thread only gets set after the internal
initialize_event_machine method has been called, the C extension is set
up, and it is entering its run loop.
This commit is contained in:
Matthew Draper 2016-11-30 22:22:36 +10:30
parent 0e97cd1a0d
commit 162e889f16
2 changed files with 28 additions and 2 deletions

@ -68,10 +68,10 @@ def redis_connection_for_broadcasts
end
def ensure_reactor_running
return if EventMachine.reactor_running?
return if EventMachine.reactor_running? && EventMachine.reactor_thread
@@mutex.synchronize do
Thread.new { EventMachine.run } unless EventMachine.reactor_running?
Thread.pass until EventMachine.reactor_running?
Thread.pass until EventMachine.reactor_running? && EventMachine.reactor_thread
end
end
end

@ -23,6 +23,32 @@ def teardown
$VERBOSE = @previous_verbose
end
def test_slow_eventmachine
require "eventmachine"
require "thread"
lock = Mutex.new
EventMachine.singleton_class.class_eval do
alias_method :delayed_initialize_event_machine, :initialize_event_machine
define_method(:initialize_event_machine) do
lock.synchronize do
sleep 0.5
delayed_initialize_event_machine
end
end
end
test_basic_broadcast
ensure
lock.synchronize do
EventMachine.singleton_class.class_eval do
alias_method :initialize_event_machine, :delayed_initialize_event_machine
remove_method :delayed_initialize_event_machine
end
end
end
def cable_config
{ adapter: "evented_redis", url: "redis://127.0.0.1:6379/12" }
end