lib/bluepill/trigger.rb in evented_bluepill-0.0.46 vs lib/bluepill/trigger.rb in evented_bluepill-0.0.47
- old
+ new
@@ -1,70 +1,72 @@
+# -*- encoding: utf-8 -*-
+
+require 'active_support'
+
module Bluepill
+ class TriggerTimer < Coolio::TimerWatcher
+ def initialize(trigger, event, delay)
+ @trigger = trigger
+ @event = event
+ super(delay, false)
+ end
+
+ def on_timer
+ begin
+ @trigger.logger.info("Retrying from flapping")
+ @trigger.dispatch!(@event)
+ @trigger.remove_timer(self)
+ rescue StandardError => e
+ @trigger.logger.err(e)
+ @trigger.logger.err(e.backtrace.join("\n"))
+ end
+ end
+ end
+
class Trigger
@implementations = {}
def self.inherited(klass)
@implementations[klass.name.split('::').last.underscore.to_sym] = klass
end
-
+
def self.[](name)
@implementations[name]
end
- attr_accessor :process, :logger, :mutex, :scheduled_events
-
+ attr_accessor :process, :logger, :scheduled_events
+
def initialize(process, options = {})
self.process = process
self.logger = options[:logger]
- self.mutex = Mutex.new
self.scheduled_events = []
end
-
+
def reset!
self.cancel_all_events
end
-
+
def notify(transition)
raise "Implement in subclass"
end
-
+
def dispatch!(event)
self.process.dispatch!(event, self.class.name.split("::").last)
end
-
- def deep_copy
- # TODO: This is a kludge. Ideally, process templates
- # would be facotries, and not a template object.
- mutex, @mutex = @mutex, nil
- clone = Marshal.load(Marshal.dump(self))
- clone.instance_variable_set("@mutex", Monitor.new)
- @mutex = mutex
- clone
+
+ def remove_timer(timer)
+ self.scheduled_events.delete(timer)
end
-
+
def schedule_event(event, delay)
- # TODO: maybe wrap this in a ScheduledEvent class with methods like cancel
- thread = Thread.new(self) do |trigger|
- begin
- sleep delay.to_f
- trigger.logger.info("Retrying from flapping")
- trigger.dispatch!(event)
- trigger.mutex.synchronize do
- trigger.scheduled_events.delete_if { |_, thread| thread == Thread.current }
- end
- rescue StandardError => e
- trigger.logger.err(e)
- trigger.logger.err(e.backtrace.join("\n"))
- end
- end
+ timer = Bluepill::TriggerTimer.new(self, event, delay)
+ self.scheduled_events << timer
- self.scheduled_events.push([event, thread])
+ Bluepill::Event.attach(timer)
end
-
+
def cancel_all_events
self.logger.info "Canceling all scheduled events"
- self.mutex.synchronize do
- self.scheduled_events.each {|_, thread| thread.kill}
- end
+ self.scheduled_events.each {|e| e.detach }
+ self.scheduled_events.clear
end
-
end
end
\ No newline at end of file