Class: PerfectQueue::Multiprocess::ChildProcessMonitor

Inherits:
Object
  • Object
show all
Defined in:
lib/perfectqueue/multiprocess/child_process_monitor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log, pid, rpipe) ⇒ ChildProcessMonitor

Returns a new instance of ChildProcessMonitor.



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 23

def initialize(log, pid, rpipe)
  @log = log
  @pid = pid
  @rpipe = rpipe
  @last_heartbeat = Time.now.to_i

  @kill_start_time = nil
  @last_kill_time = nil
  @kill_immediate = false

  @rbuf = ''
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



36
37
38
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 36

def pid
  @pid
end

Instance Method Details

#check_heartbeat(limit) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 38

def check_heartbeat(limit)
  @rpipe.read_nonblock(1024, @rbuf)
  @last_heartbeat = Time.now.to_i
  return true
rescue Errno::EINTR, Errno::EAGAIN
  return Time.now.to_i - @last_heartbeat <= limit
end

#cleanupObject



98
99
100
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 98

def cleanup
  @rpipe.close unless @rpipe.closed?
end

#killing_statusObject



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 62

def killing_status
  if @kill_start_time
    if @kill_immediate
      return true
    else
      return false
    end
  else
    return nil
  end
end

#send_signal(sig) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 102

def send_signal(sig)
  begin
    Process.kill(sig, @pid)
  rescue Errno::ESRCH, Errno::EPERM
    # TODO log?
  end
end

#start_killing(immediate, delay = 0) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 46

def start_killing(immediate, delay=0)
  if immediate && !@kill_immediate
    @kill_immediate = true  # escalation
  elsif @kill_start_time
    return
  end

  now = Time.now.to_i
  if delay == 0
    @last_kill_time = @kill_start_time = now
    kill_children(now, nil)
  else
    @last_kill_time = @kill_start_time = now + delay
  end
end

#try_join(kill_interval, graceful_kill_limit) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/perfectqueue/multiprocess/child_process_monitor.rb', line 74

def try_join(kill_interval, graceful_kill_limit)
  return nil unless @kill_start_time

  begin
    if Process.waitpid(@pid, Process::WNOHANG)
      @log.info "Processor exited and joined pid=#{@pid}"
      return true
    end
  rescue Errno::ECHILD
    # SIGCHLD is trapped in Supervisor#install_signal_handlers
    @log.info "Processor exited pid=#{@pid}"
    return true
  end

  # resend signal
  now = Time.now.to_i
  if @last_kill_time + kill_interval <= now
    kill_children(now, graceful_kill_limit)
    @last_kill_time = now
  end

  return false
end