lib/pitchfork/http_server.rb in pitchfork-0.9.0 vs lib/pitchfork/http_server.rb in pitchfork-0.10.0

- old
+ new

@@ -394,19 +394,19 @@ wait_for_pending_workers self.listeners = [] limit = Pitchfork.time_now + timeout until @children.workers.empty? || Pitchfork.time_now > limit if graceful - soft_kill_each_child(:TERM) + @children.soft_kill_all(:TERM) else - kill_each_child(:INT) + @children.hard_kill_all(:INT) end if monitor_loop(false) == StopIteration return StopIteration end end - kill_each_child(:KILL) + @children.hard_kill_all(:KILL) @promotion_lock.unlink end def worker_exit(worker) proc_name status: "exiting" @@ -504,29 +504,32 @@ next_sleep = time_left end next else # worker is out of time next_sleep = 0 - if worker.mold? - logger.error "mold pid=#{worker.pid} timed out, killing" - else - logger.error "worker=#{worker.nr} pid=#{worker.pid} timed out, killing" - end + hard_timeout(worker) + end + end - if @after_worker_hard_timeout - begin - @after_worker_hard_timeout.call(self, worker) - rescue => error - Pitchfork.log_error(@logger, "after_worker_hard_timeout callback", error) - end - end + next_sleep <= 0 ? 1 : next_sleep + end - kill_worker(:KILL, worker.pid) # take no prisoners for hard timeout violations + def hard_timeout(worker) + if @after_worker_hard_timeout + begin + @after_worker_hard_timeout.call(self, worker) + rescue => error + Pitchfork.log_error(@logger, "after_worker_hard_timeout callback", error) end end - next_sleep <= 0 ? 1 : next_sleep + if worker.mold? + logger.error "mold pid=#{worker.pid} timed out, killing" + else + logger.error "worker=#{worker.nr} pid=#{worker.pid} timed out, killing" + end + @children.hard_timeout(worker) # take no prisoners for hard timeout violations end def trigger_refork unless REFORKING_AVAILABLE logger.error("This system doesn't support PR_SET_CHILD_SUBREAPER, can't refork") @@ -695,16 +698,16 @@ env.delete('HTTP_EXPECT'.freeze) end # once a client is accepted, it is processed in its entirety here # in 3 easy steps: read request, call app, write app response - def process_client(client, timeout_handler) + def process_client(client, worker, timeout_handler) env = nil @request = Pitchfork::HttpParser.new env = @request.read(client) - proc_name status: "processing: #{env["PATH_INFO"]}" + proc_name status: "requests: #{worker.requests_count}, processing: #{env["PATH_INFO"]}" timeout_handler.rack_env = env env["pitchfork.timeout"] = timeout_handler if early_hints @@ -833,11 +836,11 @@ logger.error("worker=#{worker.nr} gen=#{worker.generation} is no longer fork safe, can't refork") end when Message worker.update(client) else - request_env = process_client(client, prepare_timeout(worker)) + request_env = process_client(client, worker, prepare_timeout(worker)) @after_request_complete&.call(self, worker, request_env) worker.increment_requests_count end worker.update_deadline(@timeout) end @@ -846,18 +849,19 @@ # timeout so we can update .deadline and keep parent from SIGKILL-ing us worker.update_deadline(@timeout) if @refork_condition && Info.fork_safe? && !worker.outdated? if @refork_condition.met?(worker, logger) + proc_name status: "requests: #{worker.requests_count}, spawning mold" if spawn_mold(worker.generation) logger.info("Refork condition met, promoting ourselves") end @refork_condition.backoff! end end - proc_name status: "waiting" + proc_name status: "requests: #{worker.requests_count}, waiting" waiter.get_readers(ready, readers, @timeout * 500) # to milliseconds, but halved rescue => e Pitchfork.log_error(@logger, "listen loop error", e) if readers[0] end end @@ -926,18 +930,9 @@ # is no longer running. def kill_worker(signal, wpid) Process.kill(signal, wpid) rescue Errno::ESRCH worker = @children.reap(wpid) and worker.close rescue nil - end - - # delivers a signal to each worker - def kill_each_child(signal) - @children.each { |w| kill_worker(signal, w.pid) } - end - - def soft_kill_each_child(signal) - @children.each { |worker| worker.soft_kill(signal) } end # returns an array of string names for the given listener array def listener_names(listeners = LISTENERS) listeners.map { |io| sock_name(io) }