class ExceptionalSynchrony::EventMachineProxy
Constants
- WRAP_WITH_ENSURE_COMPLETELY_SAFE
Attributes
connection[R]
Public Class Methods
new(proxy_class, connection_class)
click to toggle source
# 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
Public Instance Methods
add_periodic_timer(*args, &block)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
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
# 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?()
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 69 def defers_finished? @proxy_class.defers_finished? end
ensure_completely_safe(message) { || ... }
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 119 def ensure_completely_safe(message) if WRAP_WITH_ENSURE_COMPLETELY_SAFE ExceptionHandling.ensure_completely_safe(message) do yield end else yield end end
next_tick(&block)
click to toggle source
# 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?()
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 106 def reactor_running? @proxy_class.reactor_running? end
rescue_exceptions_and_ensure_exit(context) { || ... }
click to toggle source
# 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.message}" end
run(on_error: :log, &block)
click to toggle source
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
# 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() { || ... }
click to toggle source
# 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)
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 45 def sleep(seconds) @synchrony.sleep(seconds) end
stop()
click to toggle source
# 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()
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 49 def yield_to_reactor if reactor_running? @synchrony.sleep(0) end end
Private Instance Methods
run_with_error_logging(&block)
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 139 def run_with_error_logging(&block) ensure_completely_safe("run_with_error_logging") do if @proxy_class.respond_to?(:synchrony) Thread.current.thread_variable_set(:em_synchrony_reactor_thread, true) @proxy_class.synchrony(&block) else @proxy_class.run(&block) end end end
run_with_error_raising(&block)
click to toggle source
# File lib/exceptional_synchrony/event_machine_proxy.rb, line 150 def run_with_error_raising(&block) run_block = -> { rescue_exceptions_and_ensure_exit("run_with_error_raising", &block) } rescue_exceptions_and_ensure_exit("run_with_error_raising") do if @proxy_class.respond_to?(:synchrony) Thread.current.thread_variable_set(:em_synchrony_reactor_thread, true) @proxy_class.synchrony(&run_block) else @proxy_class.run(&run_block) end end end