diff options
author | Matthew Draper <matthew@trebex.net> | 2016-11-30 22:22:36 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-11-30 22:55:04 +1030 |
commit | 162e889f16ceb47978fe9bc81ac0b46672f05ff0 (patch) | |
tree | dad4cd7f849ef749c10060c50196f1b2ec670604 /actioncable | |
parent | 0e97cd1a0d3e7dbe2b99eb111e005d7c9d7002b7 (diff) | |
download | rails-162e889f16ceb47978fe9bc81ac0b46672f05ff0.tar.gz rails-162e889f16ceb47978fe9bc81ac0b46672f05ff0.tar.bz2 rails-162e889f16ceb47978fe9bc81ac0b46672f05ff0.zip |
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.
Diffstat (limited to 'actioncable')
-rw-r--r-- | actioncable/lib/action_cable/subscription_adapter/evented_redis.rb | 4 | ||||
-rw-r--r-- | actioncable/test/subscription_adapter/evented_redis_test.rb | 26 |
2 files changed, 28 insertions, 2 deletions
diff --git a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb b/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb index bcd46d2a0e..c3018c5281 100644 --- a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb +++ b/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb @@ -68,10 +68,10 @@ module ActionCable 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 diff --git a/actioncable/test/subscription_adapter/evented_redis_test.rb b/actioncable/test/subscription_adapter/evented_redis_test.rb index f316bc46ef..2401950aa7 100644 --- a/actioncable/test/subscription_adapter/evented_redis_test.rb +++ b/actioncable/test/subscription_adapter/evented_redis_test.rb @@ -23,6 +23,32 @@ class EventedRedisAdapterTest < ActionCable::TestCase $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 |