Skip to content

Commit

Permalink
Merge pull request #54 from Shopify/info-shutting-down
Browse files Browse the repository at this point in the history
Implement Pitchfork::Info.shutting_down?
  • Loading branch information
casperisfine committed Jul 17, 2023
2 parents 00956e5 + 2685d45 commit 8a369f3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Implement `before_worker_exit` callback.
- Make each mold and worker a process group leader.
- Get rid of `Pitchfork::PrereadInput`.
- Add `Pitchfork.shutting_down?` to allow health check endpoints to fail sooner on graceful shutdowns.
- Treat `TERM` as graceful shutdown rather than quick shutdown.
- Implement `after_worker_hard_timeout` callback.

Expand Down
3 changes: 3 additions & 0 deletions lib/pitchfork/http_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,11 @@ def monitor_loop(sleep = true)

master_sleep(sleep_time) if sleep
when :QUIT, :TERM # graceful shutdown
SharedMemory.shutting_down!
logger.info "#{message} received, starting graceful shutdown"
return StopIteration
when :INT # immediate shutdown
SharedMemory.shutting_down!
logger.info "#{message} received, starting immediate shutdown"
stop(false)
return StopIteration
Expand Down Expand Up @@ -375,6 +377,7 @@ def monitor_loop(sleep = true)
# Terminates all workers, but does not exit master process
def stop(graceful = true)
@respawn = false
SharedMemory.shutting_down!
wait_for_pending_workers
self.listeners = []
limit = Pitchfork.time_now + timeout
Expand Down
10 changes: 10 additions & 0 deletions lib/pitchfork/info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ def live_workers_count
SharedMemory.worker_deadline(nr).value > now
end
end

# Returns true if the server is shutting down.
# This can be useful to implement health check endpoints, so they
# can fail immediately after TERM/QUIT/INT was received by the master
# process.
# Otherwise they may succeed while Pitchfork is draining requests causing
# more requests to be sent.
def shutting_down?
SharedMemory.shutting_down?
end
end
end
end
13 changes: 11 additions & 2 deletions lib/pitchfork/shared_memory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ module SharedMemory

PER_DROP = Raindrops::PAGE_SIZE / Raindrops::SIZE
CURRENT_GENERATION_OFFSET = 0
MOLD_TICK_OFFSET = 1
WORKER_TICK_OFFSET = 2
SHUTDOWN_OFFSET = 1
MOLD_TICK_OFFSET = 2
WORKER_TICK_OFFSET = 3

DROPS = [Raindrops.new(PER_DROP)]

Expand All @@ -21,6 +22,14 @@ def current_generation=(value)
DROPS[0][CURRENT_GENERATION_OFFSET] = value
end

def shutting_down!
DROPS[0][SHUTDOWN_OFFSET] = 1
end

def shutting_down?
DROPS[0][SHUTDOWN_OFFSET] > 0
end

class Field
def initialize(offset)
@drop = DROPS.fetch(offset / PER_DROP)
Expand Down

0 comments on commit 8a369f3

Please sign in to comment.