Class: Procodile::Supervisor
- Inherits:
-
Object
- Object
- Procodile::Supervisor
- Defined in:
- lib/procodile/supervisor.rb
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#processes ⇒ Object
readonly
Returns the value of attribute processes.
-
#started_at ⇒ Object
readonly
Returns the value of attribute started_at.
-
#tag ⇒ Object
readonly
Returns the value of attribute tag.
-
#tcp_proxy ⇒ Object
readonly
Returns the value of attribute tcp_proxy.
Instance Method Summary collapse
- #add_instance(instance, io = nil) ⇒ Object
- #add_reader(instance, io) ⇒ Object
- #allow_respawning? ⇒ Boolean
- #check_concurrency(options = {}) ⇒ Object
-
#initialize(config, run_options = {}) ⇒ Supervisor
constructor
A new instance of Supervisor.
- #reload_config ⇒ Object
- #remove_instance(instance) ⇒ Object
- #restart(options = {}) ⇒ Object
- #start(&after_start) ⇒ Object
- #start_processes(types = nil, options = {}) ⇒ Object
- #stop(options = {}) ⇒ Object
- #stop_supervisor ⇒ Object
- #supervise ⇒ Object
- #to_hash ⇒ Object
Constructor Details
#initialize(config, run_options = {}) ⇒ Supervisor
Returns a new instance of Supervisor.
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/procodile/supervisor.rb', line 13 def initialize(config, = {}) @config = config @run_options = @processes = {} @readers = {} @signal_handler = SignalHandler.new('TERM', 'USR1', 'USR2', 'INT', 'HUP') @signal_handler.register('TERM') { stop_supervisor } @signal_handler.register('INT') { stop(:stop_supervisor => true) } @signal_handler.register('USR1') { restart } @signal_handler.register('USR2') { status } @signal_handler.register('HUP') { reload_config } end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
7 8 9 |
# File 'lib/procodile/supervisor.rb', line 7 def config @config end |
#processes ⇒ Object (readonly)
Returns the value of attribute processes.
8 9 10 |
# File 'lib/procodile/supervisor.rb', line 8 def processes @processes end |
#started_at ⇒ Object (readonly)
Returns the value of attribute started_at.
9 10 11 |
# File 'lib/procodile/supervisor.rb', line 9 def started_at @started_at end |
#tag ⇒ Object (readonly)
Returns the value of attribute tag.
10 11 12 |
# File 'lib/procodile/supervisor.rb', line 10 def tag @tag end |
#tcp_proxy ⇒ Object (readonly)
Returns the value of attribute tcp_proxy.
11 12 13 |
# File 'lib/procodile/supervisor.rb', line 11 def tcp_proxy @tcp_proxy end |
Instance Method Details
#add_instance(instance, io = nil) ⇒ Object
174 175 176 177 178 179 180 |
# File 'lib/procodile/supervisor.rb', line 174 def add_instance(instance, io = nil) add_reader(instance, io) if io @processes[instance.process] ||= [] unless @processes[instance.process].include?(instance) @processes[instance.process] << instance end end |
#add_reader(instance, io) ⇒ Object
169 170 171 172 |
# File 'lib/procodile/supervisor.rb', line 169 def add_reader(instance, io) @readers[io] = instance @signal_handler.notice end |
#allow_respawning? ⇒ Boolean
26 27 28 |
# File 'lib/procodile/supervisor.rb', line 26 def allow_respawning? @run_options[:respawn] != false end |
#check_concurrency(options = {}) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/procodile/supervisor.rb', line 144 def check_concurrency( = {}) Procodile.log nil, "system", "Checking process concurrency" reload_config unless [:reload] == false result = check_instance_quantities if result[:started].empty? && result[:stopped].empty? Procodile.log nil, "system", "Process concurrency looks good" else unless result[:started].empty? Procodile.log nil, "system", "Concurrency check started #{result[:started].map(&:description).join(', ')}" end unless result[:stopped].empty? Procodile.log nil, "system", "Concurrency check stopped #{result[:stopped].map(&:description).join(', ')}" end end result end |
#reload_config ⇒ Object
139 140 141 142 |
# File 'lib/procodile/supervisor.rb', line 139 def reload_config Procodile.log nil, "system", "Reloading configuration" @config.reload end |
#remove_instance(instance) ⇒ Object
182 183 184 185 186 187 |
# File 'lib/procodile/supervisor.rb', line 182 def remove_instance(instance) if @processes[instance.process] @processes[instance.process].delete(instance) @readers.delete(instance) end end |
#restart(options = {}) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/procodile/supervisor.rb', line 84 def restart( = {}) @tag = [:tag] reload_config Array.new.tap do |instances_restarted| if [:processes].nil? Procodile.log nil, "system", "Restarting all #{@config.app_name} processes" instances = @processes.values.flatten else instances = process_names_to_instances([:processes]) Procodile.log nil, "system", "Restarting #{instances.size} process(es)" end # Stop any processes that are no longer wanted at this point instances_restarted.push(*check_instance_quantities(:stopped, [:processes])[:stopped].map { |i| [i, nil]}) instances.each do |instance| next if instance.stopping? new_instance = instance.restart instances_restarted << [instance, new_instance] end # Start any processes that are needed at this point instances_restarted.push(*check_instance_quantities(:started, [:processes])[:started].map { |i| [nil, i]}) end end |
#start(&after_start) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/procodile/supervisor.rb', line 30 def start(&after_start) Procodile.log nil, "system", "Procodile supervisor started with PID #{::Process.pid}" if @run_options[:respawn] == false Procodile.log nil, "system", "Automatic respawning is disabled" end ControlServer.start(self) if @run_options[:proxy] Procodile.log nil, "system", "Proxy is enabled" @tcp_proxy = TCPProxy.start(self) end watch_for_output @started_at = Time.now after_start.call(self) if block_given? loop { supervise; sleep 3 } end |
#start_processes(types = nil, options = {}) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/procodile/supervisor.rb', line 46 def start_processes(types = nil, = {}) @tag = [:tag] reload_config 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[process] && !@processes[process].empty? # Process type already running instances = process.generate_instances(self).each(&:start) instances_started.push(*instances) end end end |
#stop(options = {}) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/procodile/supervisor.rb', line 59 def stop( = {}) if [:stop_supervisor] @run_options[:stop_when_none] = true end reload_config Array.new.tap do |instances_stopped| if [:processes].nil? 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([:processes]) Procodile.log nil, "system", "Stopping #{instances.size} process(es)" instances.each do |instance| instance.stop instances_stopped << instance end end end end |
#stop_supervisor ⇒ Object
110 111 112 113 114 |
# File 'lib/procodile/supervisor.rb', line 110 def stop_supervisor Procodile.log nil, 'system', "Stopping Procodile supervisor" FileUtils.rm_f(File.join(@config.pid_root, 'procodile.pid')) ::Process.exit 0 end |
#supervise ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/procodile/supervisor.rb', line 116 def supervise # Tell instances that have been stopped that they have been stopped remove_stopped_instances # Remove removed processes remove_removed_processes # Check all instances that we manage and let them do their things. @processes.each do |_, instances| instances.each do |instance| instance.check end end if @run_options[:stop_when_none] # If the processes go away, we can stop the supervisor now if @processes.all? { |_,instances| instances.size == 0 } Procodile.log nil, "system", "All processes have stopped" stop_supervisor end end end |
#to_hash ⇒ Object
162 163 164 165 166 167 |
# File 'lib/procodile/supervisor.rb', line 162 def to_hash { :started_at => @started_at ? @started_at.to_i : nil, :pid => ::Process.pid } end |