Class: ProcessBot::Process::Handlers::Sidekiq
- Inherits:
-
Object
- Object
- ProcessBot::Process::Handlers::Sidekiq
- Defined in:
- lib/process_bot/process/handlers/sidekiq.rb
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#process ⇒ Object
readonly
Returns the value of attribute process.
Instance Method Summary collapse
- #current_pid ⇒ Object
- #daemonize ⇒ Object
- #ensure_current_pid? ⇒ Boolean
- #fetch ⇒ Object
- #graceful(stop_process_bot: true, **_args) ⇒ Object
- #graceful_no_wait(stop_process_bot: true, **_args) ⇒ Object
-
#initialize(process) ⇒ Sidekiq
constructor
A new instance of Sidekiq.
- #logger ⇒ Object
- #process_running?(pid) ⇒ Boolean
- #refresh_current_pid(only_if_present: false) ⇒ Object
- #related_sidekiq_pid ⇒ Object
- #send_tstp_or_return ⇒ Object
- #set ⇒ Object
- #set_option(key, value) ⇒ Object
-
#start_command ⇒ Object
rubocop:disable Metrics/AbcSize.
- #stop(**_args) ⇒ Object
- #terminate_pid(pid) ⇒ Object
- #terminate_related_sidekiq_processes ⇒ Object
- #update_current_pid(new_pid) ⇒ Object
-
#wait_for_no_jobs ⇒ Object
rubocop:disable Metrics/AbcSize.
- #wait_for_no_jobs_and_stop_sidekiq ⇒ Object
- #wait_for_sidekiq_exit ⇒ Object
Constructor Details
#initialize(process) ⇒ Sidekiq
Returns a new instance of Sidekiq.
4 5 6 7 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 4 def initialize(process) @process = process @options = process. end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
2 3 4 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 2 def @options end |
#process ⇒ Object (readonly)
Returns the value of attribute process.
2 3 4 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 2 def process @process end |
Instance Method Details
#current_pid ⇒ Object
9 10 11 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 9 def current_pid process.current_pid end |
#daemonize ⇒ Object
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 13 def daemonize logger.logs "Daemonize!" pid = Process.fork do Process.daemon yield end Process.detach(pid) if pid end |
#ensure_current_pid? ⇒ Boolean
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 86 def ensure_current_pid? unless current_pid warn "Sidekiq not running with a PID" return false end unless refresh_current_pid logger.logs "Sidekiq PID not running and no replacement found - nothing to stop" return false end true end |
#fetch ⇒ Object
59 60 61 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 59 def fetch(*, **) .fetch(*, **) end |
#graceful(stop_process_bot: true, **_args) ⇒ Object
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 144 def graceful(stop_process_bot: true, **_args) process.set_stopped if stop_process_bot return unless ensure_current_pid? return unless send_tstp_or_return logger.logs "Wait for gracefully stopped..." wait_for_no_jobs_and_stop_sidekiq end |
#graceful_no_wait(stop_process_bot: true, **_args) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 155 def graceful_no_wait(stop_process_bot: true, **_args) process.set_stopped if stop_process_bot return unless ensure_current_pid? return unless send_tstp_or_return logger.logs "Dont wait for gracefully stopped - doing that in fork..." daemonize do wait_for_no_jobs_and_stop_sidekiq exit end end |
#logger ⇒ Object
63 64 65 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 63 def logger @logger ||= ProcessBot::Logger.new(options: ) end |
#process_running?(pid) ⇒ Boolean
24 25 26 27 28 29 30 31 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 24 def process_running?(pid) return false unless pid Process.getpgid(pid) true rescue Errno::ESRCH false end |
#refresh_current_pid(only_if_present: false) ⇒ Object
49 50 51 52 53 54 55 56 57 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 49 def refresh_current_pid(only_if_present: false) return nil if only_if_present && !current_pid return current_pid if process_running?(current_pid) new_pid = return nil unless new_pid update_current_pid(new_pid) end |
#related_sidekiq_pid ⇒ Object
33 34 35 36 37 38 39 40 41 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 33 def = process.runner. if .empty? logger.logs "No related Sidekiq processes found while refreshing PID" return nil end .first.pid end |
#send_tstp_or_return ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 77 def send_tstp_or_return logger.logs "Killing process with signal TSTP for PID #{current_pid}" Process.kill("TSTP", current_pid) true rescue Errno::ESRCH logger.logs "Sidekiq PID #{current_pid} disappeared before TSTP" false end |
#set ⇒ Object
73 74 75 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 73 def set(*, **) .set(*, **) end |
#set_option(key, value) ⇒ Object
67 68 69 70 71 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 67 def set_option(key, value) raise "Unknown option for Sidekiq handler: #{key}" unless .key?(key) set(key, value) end |
#start_command ⇒ Object
rubocop:disable Metrics/AbcSize
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 120 def start_command # rubocop:disable Metrics/AbcSize args = [] ..each do |key, value| next unless (match = key.to_s.match(/\Asidekiq_(.+)\Z/)) sidekiq_key = match[1] if sidekiq_key == "queue" value.split(",").each do |queue| args.push "--queue #{queue}" end else args.push "--#{sidekiq_key} #{value}" end end command = "bash -c 'cd #{.fetch(:release_path)} && exec " command << "#{.fetch(:bundle_prefix)} " if .present?(:bundle_prefix) command << "bundle exec sidekiq #{args.compact.join(' ')}" command << "'" command end |
#stop(**_args) ⇒ Object
169 170 171 172 173 174 175 176 177 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 169 def stop(**_args) refresh_current_pid(only_if_present: true) if current_pid terminate_pid(current_pid) else end end |
#terminate_pid(pid) ⇒ Object
100 101 102 103 104 105 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 100 def terminate_pid(pid) logger.logs "Killing process with signal TERM for PID #{pid}" Process.kill("TERM", pid) rescue Errno::ESRCH logger.logs "Sidekiq PID #{pid} is not running - nothing to stop" end |
#terminate_related_sidekiq_processes ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 107 def = process.runner. if .empty? logger.error "#{handler_name} didn't have any processes running" return end .each do || terminate_pid(.pid) end end |
#update_current_pid(new_pid) ⇒ Object
43 44 45 46 47 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 43 def update_current_pid(new_pid) logger.logs "Refreshing Sidekiq PID from #{current_pid || 'nil'} to #{new_pid}" .events.call(:on_process_started, pid: new_pid) new_pid end |
#wait_for_no_jobs ⇒ Object
rubocop:disable Metrics/AbcSize
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 179 def wait_for_no_jobs # rubocop:disable Metrics/AbcSize loop do found_process = false unless refresh_current_pid logger.logs "Sidekiq PID not running while waiting for jobs" return end Knj::Unix_proc.list("grep" => current_pid) do |process| process_command = process.data.fetch("cmd") process_pid = process.data.fetch("pid").to_i next unless process_pid == current_pid found_process = true sidekiq_regex = /\Asidekiq (\d+).(\d+).(\d+) (#{.possible_process_titles_joined_regex}) \[(\d+) of (\d+)(\]|) (.+?)(\]|)\Z/ match = process_command.match(sidekiq_regex) raise "Couldnt match Sidekiq command: #{process_command} with Sidekiq regex: #{sidekiq_regex}" unless match running_jobs = match[5].to_i logger.logs "running_jobs: #{running_jobs}" return if running_jobs.zero? # rubocop:disable Lint/NonLocalExitFromIterator end unless found_process logger.logs "Couldn't find running process with PID #{current_pid}" return end sleep 1 end end |
#wait_for_no_jobs_and_stop_sidekiq ⇒ Object
214 215 216 217 218 219 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 214 def wait_for_no_jobs_and_stop_sidekiq logger.logs "Wait for no jobs and Stop sidekiq" wait_for_no_jobs stop wait_for_sidekiq_exit end |
#wait_for_sidekiq_exit ⇒ Object
221 222 223 224 225 226 227 228 |
# File 'lib/process_bot/process/handlers/sidekiq.rb', line 221 def wait_for_sidekiq_exit return unless current_pid while process_running?(current_pid) logger.logs "Waiting for Sidekiq PID #{current_pid} to stop" sleep 1 end end |