remove gods pid file on user requested termination
[god.git] / lib / god / timer.rb
blob913267a24602f1daf95e074fc54a608d8bb354fc
1 module God
2   
3   class TimerEvent
4     attr_accessor :condition, :at
5     
6     def initialize(condition, interval)
7       self.condition = condition
8       self.at = Time.now.to_i + interval
9     end
10   end
11   
12   class Timer
13     INTERVAL = 0.25
14     
15     attr_reader :events, :timer
16     
17     @@timer = nil
18     
19     def self.get
20       @@timer ||= Timer.new
21     end
22     
23     def self.reset
24       @@timer = nil
25     end
26     
27     # Start the scheduler loop to handle events
28     def initialize
29       @events = []
30       @mutex = Mutex.new
31       
32       @timer = Thread.new do
33         loop do
34           begin
35             # get the current time
36             t = Time.now.to_i
37           
38             # iterate over each event and trigger any that are due
39             @events.each do |event|
40               if t >= event.at
41                 self.trigger(event)
42                 @mutex.synchronize do
43                   @events.delete(event)
44                 end
45               else
46                 break
47               end
48             end
49           
50             # sleep until next check
51             sleep INTERVAL
52           rescue Exception => e
53             message = format("Unhandled exception (%s): %s\n%s",
54                              e.class, e.message, e.backtrace.join("\n"))
55             applog(nil, :fatal, message)
56             sleep INTERVAL
57           end
58         end
59       end
60     end
61     
62     # Create and register a new TimerEvent with the given parameters
63     def schedule(condition, interval = condition.interval)
64       @mutex.synchronize do
65         @events << TimerEvent.new(condition, interval)
66         @events.sort! { |x, y| x.at <=> y.at }
67       end
68     end
69     
70     # Remove any TimerEvents for the given condition
71     def unschedule(condition)
72       @mutex.synchronize do
73         @events.reject! { |x| x.condition == condition }
74       end
75     end
76     
77     def trigger(event)
78       Hub.trigger(event.condition)
79     end
80     
81     # Join the timer thread
82     def join
83       @timer.join
84     end
85   end
86   
87 end