more diagnostics
[god.git] / lib / god / event_handler.rb
blobc1ea8474d74c4df02e78e78a5ca1cb959d9155f6
1 module God
2   class EventHandler
3     @@actions = {}
4     @@handler = nil
5     @@loaded = false
6     
7     def self.loaded?
8       @@loaded
9     end
10     
11     def self.event_system
12       @@handler::EVENT_SYSTEM
13     end
14     
15     def self.load
16       begin
17         case RUBY_PLATFORM
18         when /darwin/i, /bsd/i
19           require 'god/event_handlers/kqueue_handler'
20           @@handler = KQueueHandler
21         when /linux/i
22           require 'god/event_handlers/netlink_handler'
23           @@handler = NetlinkHandler
24         else
25           raise NotImplementedError, "Platform not supported for EventHandler"
26         end
27         @@loaded = true
28       rescue Exception
29         require 'god/event_handlers/dummy_handler'
30         @@handler = DummyHandler
31         @@loaded = false
32       end
33     end
34     
35     def self.register(pid, event, &block)
36       @@actions[pid] ||= {}
37       @@actions[pid][event] = block
38       @@handler.register_process(pid, @@actions[pid].keys)
39     end
40     
41     def self.deregister(pid, event=nil)
42       if watching_pid? pid
43         if event.nil?
44           @@actions.delete(pid)
45           @@handler.register_process(pid, []) if system("kill -0 #{pid} &> /dev/null")
46         else
47           @@actions[pid].delete(event)
48           @@handler.register_process(pid, @@actions[pid].keys) if system("kill -0 #{pid} &> /dev/null")
49         end
50       end
51     end
52     
53     def self.call(pid, event, extra_data = {})
54       @@actions[pid][event].call(extra_data) if watching_pid?(pid) && @@actions[pid][event]
55     end
56     
57     def self.watching_pid?(pid)
58       @@actions[pid]
59     end
60     
61     def self.start
62       Thread.new do
63         loop do
64           begin
65             @@handler.handle_events
66           rescue Exception => e
67             message = format("Unhandled exception (%s): %s\n%s",
68                              e.class, e.message, e.backtrace.join("\n"))
69             applog(nil, :fatal, message)
70           end
71         end
72       end
73     end
74     
75   end
76 end