class Eventr::SupervisedObject
Attributes
on_exception[R]
Public Instance Methods
application()
click to toggle source
# File lib/eventr/actors.rb, line 39 def application threads[:application] end
on_exception=(&block)
click to toggle source
# File lib/eventr/actors.rb, line 47 def on_exception=(&block) # rubocop:disable TrivialAccessors @on_exception = block end
sleep_time_from_backoff()
click to toggle source
# File lib/eventr/actors.rb, line 51 def sleep_time_from_backoff backoff = Thread.current[:backoff] || 0 (0..backoff).inject([1, 0]) { |(a, b), _| [b, a + b] }[0] end
start()
click to toggle source
# File lib/eventr/actors.rb, line 30 def start start_application_thread start_supervisor_thread end
start_application_thread()
click to toggle source
# File lib/eventr/actors.rb, line 56 def start_application_thread threads[:application] ||= Thread.new do begin main rescue StandardError => e on_exception.call(e) if on_exception.respond_to? :call warn "#{e.class.name}: #{e.message}\n\t#{e.backtrace.join("\n\t")}" raise e ensure threads[:supervisor].wakeup # wakeup the supervisor to help us recover end end end
start_supervisor_thread()
click to toggle source
# File lib/eventr/actors.rb, line 70 def start_supervisor_thread # rubocop:disable MethodLength threads[:supervisor] ||= Thread.new do Thread.current[:backoff] = 1 begin runs = 5 loop do unless application && application.alive? puts "#{self.class.name}::Supervisor: cleaning up app thread and restarting it." threads[:application] = nil start_application_thread # stop when we've successfully cleaned something up runs = 0 # and make sure to reset backoff Thread.current[:backoff] = 1 end # check for required cleanup 5 times over as many seconds if (runs -= 1) <= 0 Thread.stop runs = 5 end sleep 1 end rescue StandardError => e warn "#{e.class.name}: #{e.message}\n\t#{e.backtrace.join("\n\t")}" if Thread.current[:backoff] <= 15 Thread.current[:backoff] += 1 sleep_time = sleep_time_from_backoff warn "sleeping for #{sleep_time} before restarting supervisor" sleep sleep_Time retry end # if the supervisor goes away, take the whole thing down. error_msg = "supervisor went away due to: #{e.class.name}: #{e.message} -> #{e.backtrace.first}" threads[:application].raise Error::SupervisorDown, error_msg raise e end end end
stop()
click to toggle source
# File lib/eventr/actors.rb, line 26 def stop threads.values.each { |t| t.send :kill } end
supervisor()
click to toggle source
# File lib/eventr/actors.rb, line 43 def supervisor threads[:supervisor] end
threads()
click to toggle source
# File lib/eventr/actors.rb, line 35 def threads @threads ||= {} end