Class: Navy::Admiral
Defined Under Namespace
Constant Summary collapse
- CAPTAINS =
This hash maps PIDs to Captains
{}
- RESPAWNS =
{}
- SELF_PIPE =
[]
- SIG_QUEUE =
signal queue used for self-piping
[]
- QUEUE_SIGS =
list of signals we care about and trap in admiral.
[ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
- START_CTX =
{ :argv => ARGV.map { |arg| arg.dup }, 0 => $0.dup, }
Instance Attribute Summary collapse
-
#admiral_pid ⇒ Object
Returns the value of attribute admiral_pid.
-
#before_exec ⇒ Object
callbacks ##.
-
#captains ⇒ Object
Returns the value of attribute captains.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Attributes inherited from Rank
#after_fork, #after_stop, #before_fork, #before_stop, #current_stderr, #current_stdout, #heartbeat, #logger, #orders, #orig_stderr, #orig_stdout, #patience, #pid, #post_fork, #preload, #reexec_pid, #respawn_limit, #respawn_limit_seconds, #stderr_path, #stdout_path, #timeout
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ Admiral
constructor
A new instance of Admiral.
- #join ⇒ Object
- #start ⇒ Object
-
#stop(graceful = true) ⇒ Object
Terminates all captains, but does not exit admiral process.
Constructor Details
#initialize(options = {}) ⇒ Admiral
Returns a new instance of Admiral.
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/navy/admiral.rb', line 35 def initialize( = {}) self.orig_stderr = $stderr.dup self.orig_stdout = $stdout.dup self.reexec_pid = 0 @options = .dup @ready_pipe = @options.delete(:ready_pipe) @options[:use_defaults] = true self.orders = Navy::Admiral::Orders.new(self.class, @options) orders.give!(self, except: [ :stderr_path, :stdout_path ]) end |
Instance Attribute Details
#admiral_pid ⇒ Object
Returns the value of attribute admiral_pid.
32 33 34 |
# File 'lib/navy/admiral.rb', line 32 def admiral_pid @admiral_pid end |
#before_exec ⇒ Object
callbacks ##
30 31 32 |
# File 'lib/navy/admiral.rb', line 30 def before_exec @before_exec end |
#captains ⇒ Object
Returns the value of attribute captains.
32 33 34 |
# File 'lib/navy/admiral.rb', line 32 def captains @captains end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
33 34 35 |
# File 'lib/navy/admiral.rb', line 33 def @options end |
Instance Method Details
#join ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/navy/admiral.rb', line 68 def join respawn = true last_check = Time.now proc_name 'admiral' logger.info "admiral process ready" if @ready_pipe @ready_pipe.syswrite($$.to_s) @ready_pipe = @ready_pipe.close rescue nil end begin reap_all_captains case SIG_QUEUE.shift when nil # avoid murdering workers after our master process (or the # machine) comes out of suspend/hibernation heartbeat.call(self) if heartbeat if (last_check + @timeout) >= (last_check = Time.now) sleep_time = murder_lazy_captains logger.debug("would normally murder lazy captains") if $DEBUG else sleep_time = @timeout/2.0 + 1 logger.debug("waiting #{sleep_time}s after suspend/hibernation") end maintain_captain_count if respawn admiral_sleep(sleep_time) when :QUIT # graceful shutdown break when :TERM, :INT # immediate shutdown stop(false) break when :USR1 # rotate logs logger.info "admiral reopening logs..." Navy::Util.reopen_logs logger.info "admiral done reopening logs" kill_each_captain(:USR1) when :USR2 # exec binary, stay alive in case something went wrong reexec when :WINCH # if Unicorn::Configurator::RACKUP[:daemonized] # respawn = false # logger.info "gracefully stopping all workers" # kill_each_worker(:QUIT) # self.worker_processes = 0 # else logger.info "SIGWINCH ignored because we're not daemonized" # end when :TTIN respawn = true kill_each_captain(:TTIN) when :TTOU kill_each_captain(:TTOU) when :HUP respawn = true # if config.config_file # load_config! # else # exec binary and exit if there's no config file logger.info "config_file not present, reexecuting binary" reexec # end end rescue => e Navy.log_error(logger, "admiral loop error", e) end while true stop # gracefully shutdown all captains on our way out logger.info "admiral complete" end |
#start ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/navy/admiral.rb', line 48 def start orders.give!(self, only: [ :stderr_path, :stdout_path ]) init_self_pipe! QUEUE_SIGS.each do |sig| trap(sig) do logger.debug "admiral received #{sig}" if $DEBUG SIG_QUEUE << sig awaken_admiral end end trap(:CHLD) { awaken_admiral } logger.info "admiral starting" self.admiral_pid = $$ preload.call(self) if preload spawn_missing_captains self end |
#stop(graceful = true) ⇒ Object
Terminates all captains, but does not exit admiral process
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/navy/admiral.rb', line 137 def stop(graceful = true) before_stop.call(self, graceful) if before_stop limit = Time.now + patience until CAPTAINS.empty? || (n = Time.now) > limit kill_each_captain(graceful ? :QUIT : :TERM) sleep(0.1) reap_all_captains end if n and n > limit logger.debug "admiral patience exceeded by #{n - limit} seconds (limit #{patience} seconds)" if $DEBUG end kill_each_captain(:KILL) after_stop.call(self, graceful) if after_stop end |