Class: Procodile::Supervisor

Inherits:
Object
  • Object
show all
Defined in:
lib/procodile/supervisor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Supervisor

Create a new supervisor instance that will be monitoring the processes that have been provided.



11
12
13
14
15
16
17
18
19
20
# File 'lib/procodile/supervisor.rb', line 11

def initialize(config)
  @config = config
  @processes = {}
  signal_handler = SignalHandler.new('TERM', 'USR1', 'USR2', 'INT', 'HUP')
  signal_handler.register('TERM') { stop_supervisor }
  signal_handler.register('INT') { stop }
  signal_handler.register('USR1') { restart }
  signal_handler.register('USR2') { status }
  signal_handler.register('HUP') { reload_config }
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



6
7
8
# File 'lib/procodile/supervisor.rb', line 6

def config
  @config
end

#processesObject (readonly)

Returns the value of attribute processes.



7
8
9
# File 'lib/procodile/supervisor.rb', line 7

def processes
  @processes
end

Instance Method Details

#reload_configObject



118
119
120
121
122
# File 'lib/procodile/supervisor.rb', line 118

def reload_config
  Procodile.log nil, "system", "Reloading configuration"
  @config.reload
  check_instance_quantities
end

#restart(options = {}) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/procodile/supervisor.rb', line 66

def restart(options = {})
  @config.reload
  Array.new.tap do |instances_restarted|
    if options[:processes].nil?
      Procodile.log nil, "system", "Restarting all #{@config.app_name} processes"
      @processes.each do |_, instances|
        instances.each do |instance|
          instance.restart
          instances_restarted << instance
        end
      end
    else
      instances = process_names_to_instances(options[:processes])
      Procodile.log nil, "system", "Restarting #{instances.size} process(es)"
      instances.each do |instance|
        instance.restart
        instances_restarted << instance
      end
    end
  end
end

#start(options = {}) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/procodile/supervisor.rb', line 22

def start(options = {})
  Procodile.log nil, "system", "#{@config.app_name} supervisor started with PID #{::Process.pid}"
  Thread.new do
    socket = ControlServer.new(self)
    socket.listen
  end
  start_processes(options[:processes])
  supervise
end

#start_processes(types = []) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/procodile/supervisor.rb', line 32

def start_processes(types = [])
  Array.new.tap do |instances_started|
    @config.processes.each do |name, process|
      next if types && !types.include?(name.to_s) # Not a process we want
      next if @processes.keys.include?(process)   # Process type already running
      instances = start_instances(process.generate_instances)
      instances_started.push(*instances)
    end
  end
end

#stop(options = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/procodile/supervisor.rb', line 43

def stop(options = {})
  Array.new.tap do |instances_stopped|
    if options[:processes].nil?
      return if @stopping
      @stopping = true
      Procodile.log nil, "system", "Stopping all #{@config.app_name} processes"
        @processes.each do |_, instances|
          instances.each do |instance|
            instance.stop
            instances_stopped << instance
          end
        end
    else
      instances = process_names_to_instances(options[:processes])
      Procodile.log nil, "system", "Stopping #{instances.size} process(es)"
      instances.each do |instance|
        instance.stop
        instances_stopped << instance
      end
    end
  end
end

#stop_supervisorObject



88
89
90
91
92
# File 'lib/procodile/supervisor.rb', line 88

def stop_supervisor
  Procodile.log nil, 'system', "Stopping #{@config.app_name} supervisor"
  FileUtils.rm_f(File.join(@config.pid_root, 'supervisor.pid'))
  ::Process.exit 0
end

#superviseObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/procodile/supervisor.rb', line 94

def supervise
  loop do
    # Tidy up any instances that we no longer wish to be managed. They will
    # be removed from the list.
    remove_dead_instances

    # Remove processes that have been stopped
    remove_stopped_instances

    # Check all instances that we manage and let them do their things.
    @processes.each do |_, instances|
      instances.each(&:check)
    end

    # If the processes go away, we can stop the supervisor now
    if @processes.size == 0
      Procodile.log nil, "system", "All processes have stopped"
      stop_supervisor
    end

    sleep 5
  end
end