Class: PoolParty::MonitorDaemon

Inherits:
Monitors::BaseMonitor show all
Defined in:
lib/poolparty/monitors/monitor_daemon.rb

Instance Attribute Summary collapse

Attributes inherited from Monitors::BaseMonitor

#last_cloud_loaded_time, #log_file_path

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Monitors::BaseMonitor

#after_close_callbacks, #before_close_callbacks, #env, inherited, #log, #my_cloud

Constructor Details

#initialize(o = {}) ⇒ MonitorDaemon

Returns a new instance of MonitorDaemon.



14
15
16
17
18
19
20
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 14

def initialize(o={})
  @should_daemonize = o.delete(:daemonize)
  @pid_file = o.delete(:daemonize) || "/tmp/poolparty_monitor.pid"
  @sleep_time = o.delete(:sleep_time) || 20
        
  super
end

Instance Attribute Details

#pid_fileObject (readonly)

Returns the value of attribute pid_file.



8
9
10
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 8

def pid_file
  @pid_file
end

#should_daemonizeObject (readonly)

Returns the value of attribute should_daemonize.



8
9
10
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 8

def should_daemonize
  @should_daemonize
end

#sleep_timeObject (readonly)

Returns the value of attribute sleep_time.



8
9
10
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 8

def sleep_time
  @sleep_time
end

Class Method Details

.run(o = {}) ⇒ Object



10
11
12
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 10

def self.run(o={})
  new(o).run
end

Instance Method Details

#daemonize(o = {}) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 62

def daemonize(o={})
  raise unless pid_file
  
  pwd = Dir.pwd # Current directory is changed during daemonization, so store it
  
  remove_stale_pid_file
  pid = fork do
    Signal.trap('HUP') do
      restart
    end
    Signal.trap('INT') do
      stop!
    end
    Signal.trap("CHLD") do 
      Process.waitpid(pid, Process::WNOHANG)
    end
    File.open("/dev/null", "r+") do |devnull|
      $stdout.reopen(devnull)
      $stderr.reopen(devnull)
      $stdin.reopen(devnull) unless @use_stdin
    end
    run
  end
  
  Dir.chdir(pwd)
  
  write_pid_file(pid)

  Process.detach(pid)
end

#pass_the_batonObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 22

def pass_the_baton
  # Handle stats
  my_nominations = JSON.parse(open("http://localhost:8642/stats/get_nominations").read)
  unless my_nominations.empty?
    running_nodes = my_cloud.nodes(:status => "running")
    nominations = []
    running_nodes.each do |node|
      timeout(10) do
        log "Checking with #{node.internal_ip} for nominations: #{open("http://#{node.internal_ip}:8642/stats/get_nominations").read}"
        nominations << begin
          JSON.parse(open("http://#{node.internal_ip}:8642/stats/nominations").read) || "none"
        rescue
          log "Error when connecting to #{node.internal_ip}: #{e.inspect}"
          "none"
        end            
      end
    end
    log "Sending #{nominations.flatten.to_json} to #{server["/elections"].inspect}"
    # put to "http://localhost:8642/elections/handle_election", data => nominations.to_json
    server["/elections"].put(nominations.flatten.to_json)
  end
end

#pidObject



93
94
95
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 93

def pid
  @pid ||= File.file?(pid_file) ? open(pid_file).read.to_i : nil
end

#restartObject



105
106
107
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 105

def restart
  log "TODO: implement restart for HUP signal on #{__FILE__}"
end

#runObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 45

def run      
  if should_daemonize
    @should_daemonize = false
    daemonize
  else
    log "Starting MonitorDaemon"
    loop {          
      begin
        pass_the_baton
      rescue Exception => e
        log "There was an error with pass_the_baton: #{e}"
      end
      sleep sleep_time
    }
  end
end

#running?Boolean

Returns:

  • (Boolean)


109
110
111
112
113
114
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 109

def running?
  return false unless pid
  Process.getpgid(pid) != -1
rescue Errno::ESRCH
  false
end

#send_signal(signal) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 116

def send_signal(signal)
  if File.exist?(pid_file) && pid = open(pid_file).read
    pid = pid.to_i
    print "Sending #{signal} signal to process #{pid} ... "
    Process.kill(signal, pid)
    puts
    pid
  else
    puts "Can't stop process, no PID found in #{pid_file}"
    nil
  end
rescue Errno::ESRCH # No such process
  puts "process not found!"
  nil
end

#stop!Object



97
98
99
100
101
102
103
# File 'lib/poolparty/monitors/monitor_daemon.rb', line 97

def stop!
  log "Stopping daemon"
  log_file.close
  send_signal("INT")
  remove_stale_pid_file
  exit 0
end