Class: ExceptionalSynchrony::EventMachineProxy
- Inherits:
-
Object
- Object
- ExceptionalSynchrony::EventMachineProxy
- Defined in:
- lib/exceptional_synchrony/event_machine_proxy.rb
Constant Summary collapse
- WRAP_WITH_ENSURE_COMPLETELY_SAFE =
(ENV['RACK_ENV'] != 'test')
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
Instance Method Summary collapse
- #add_periodic_timer(*args, &block) ⇒ Object
- #add_timer(seconds, &block) ⇒ Object
- #connect(server, port = nil, handler = nil, *args, &block) ⇒ Object
-
#defer(_context = nil, wait_for_result: true, &block) ⇒ Object
This method will execute the block on the background thread pool By default, it will block the caller until the background thread has finished, so that the result can be returned :wait_for_result - setting this to false will prevent the caller from being blocked by this deferred work.
- #defers_finished? ⇒ Boolean
- #ensure_completely_safe(message) ⇒ Object
-
#initialize(proxy_class, connection_class) ⇒ EventMachineProxy
constructor
A new instance of EventMachineProxy.
- #next_tick(&block) ⇒ Object
- #reactor_running? ⇒ Boolean
- #rescue_exceptions_and_ensure_exit(context) ⇒ Object
-
#run(on_error: :log, &block) ⇒ Object
This method starts the EventMachine reactor.
- #run_and_stop ⇒ Object
- #sleep(seconds) ⇒ Object
- #stop ⇒ Object
- #yield_to_reactor ⇒ Object
Constructor Details
#initialize(proxy_class, connection_class) ⇒ EventMachineProxy
Returns a new instance of EventMachineProxy.
19 20 21 22 23 24 25 26 27 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 19 def initialize(proxy_class, connection_class) @proxy_class = proxy_class @synchrony = defined?(@proxy_class::Synchrony) ? @proxy_class::Synchrony : @proxy_class @connection = connection_class proxy_class.error_handler do |error| ExceptionHandling.log_error(error, "ExceptionalSynchrony uncaught exception: ") end end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
15 16 17 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 15 def connection @connection end |
Instance Method Details
#add_periodic_timer(*args, &block) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 37 def add_periodic_timer(*args, &block) @synchrony.add_periodic_timer(*args) do ensure_completely_safe("add_periodic_timer") do block.call end end end |
#add_timer(seconds, &block) ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 29 def add_timer(seconds, &block) @synchrony.add_timer(seconds) do ensure_completely_safe("add_timer") do block.call end end end |
#connect(server, port = nil, handler = nil, *args, &block) ⇒ Object
73 74 75 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 73 def connect(server, port = nil, handler = nil, *args, &block) @proxy_class.connect(server, port, handler, *args, &block) end |
#defer(_context = nil, wait_for_result: true, &block) ⇒ Object
This method will execute the block on the background thread pool By default, it will block the caller until the background thread has finished, so that the result can be returned
:wait_for_result - setting this to false will prevent the caller from being blocked by this deferred work
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 92 def defer(_context = nil, wait_for_result: true, &block) if wait_for_result deferrable = EventMachine::DefaultDeferrable.new callback = -> (result) { deferrable.succeed(result) } EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) } EventMachine::Synchrony.sync(deferrable) CallbackExceptions.map_deferred_result(deferrable) else EventMachine.defer { ExceptionHandling.ensure_completely_safe("defer", &block) } nil end end |
#defers_finished? ⇒ Boolean
69 70 71 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 69 def defers_finished? @proxy_class.defers_finished? end |
#ensure_completely_safe(message) ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 119 def ensure_completely_safe() if WRAP_WITH_ENSURE_COMPLETELY_SAFE ExceptionHandling.ensure_completely_safe() do yield end else yield end end |
#next_tick(&block) ⇒ Object
55 56 57 58 59 60 61 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 55 def next_tick(&block) @synchrony.next_tick do ensure_completely_safe("next_tick") do block.call end end end |
#reactor_running? ⇒ Boolean
106 107 108 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 106 def reactor_running? @proxy_class.reactor_running? end |
#rescue_exceptions_and_ensure_exit(context) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 129 def rescue_exceptions_and_ensure_exit(context) yield rescue StandardError => ex # Raise a non-StandardError so that not caught by EM.error_handler. # Expecting rescued exception to be stored in this new exception's cause. raise FatalRunError, "Fatal EventMachine #{context} error\n#{ex.class.name}: #{ex.}" end |
#run(on_error: :log, &block) ⇒ Object
This method starts the EventMachine reactor. The on_error option has these possible values:
:log - log any rescued StandardError exceptions and continue
:raise - raise FatalRunError for any rescued StandardError exceptions
81 82 83 84 85 86 87 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 81 def run(on_error: :log, &block) case on_error when :log then run_with_error_logging(&block) when :raise then run_with_error_raising(&block) else raise ArgumentError, "Invalid on_error: #{on_error.inspect}, must be :log or :raise" end end |
#run_and_stop ⇒ Object
110 111 112 113 114 115 116 117 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 110 def run_and_stop ret = nil run do ret = yield stop end ret end |
#sleep(seconds) ⇒ Object
45 46 47 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 45 def sleep(seconds) @synchrony.sleep(seconds) end |
#stop ⇒ Object
63 64 65 66 67 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 63 def stop @proxy_class.stop @proxy_class.next_tick { } #Fake out EventMachine's epoll mechanism so we don't block until timers fire Thread.current.thread_variable_set(:em_synchrony_reactor_thread, false) end |
#yield_to_reactor ⇒ Object
49 50 51 52 53 |
# File 'lib/exceptional_synchrony/event_machine_proxy.rb', line 49 def yield_to_reactor if reactor_running? @synchrony.sleep(0) end end |