Skip to content

Commit

Permalink
Use a Concurrent::Event for CLI signal-trapping loop (#1141)
Browse files Browse the repository at this point in the history
  • Loading branch information
bensheldon authored Nov 6, 2023
1 parent af9f04d commit 2b698b6
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
12 changes: 8 additions & 4 deletions lib/good_job/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class CLI < Thor
# Requiring this loads the application's configuration and classes.
RAILS_ENVIRONMENT_RB = File.expand_path("config/environment.rb")

# Number of seconds between checking shutdown conditions
SHUTDOWN_EVENT_TIMEOUT = 10

class << self
# Whether the CLI is running from the executable
# @return [Boolean, nil]
Expand Down Expand Up @@ -106,14 +109,15 @@ def start
probe_server.start
end

@stop_good_job_executable = false
require 'concurrent/atomic/event'
@stop_good_job_executable = Concurrent::Event.new
%w[INT TERM].each do |signal|
trap(signal) { @stop_good_job_executable = true }
trap(signal) { Thread.new { @stop_good_job_executable.set }.join }
end

Kernel.loop do
sleep 0.1
break if @stop_good_job_executable || capsule.shutdown?
@stop_good_job_executable.wait(SHUTDOWN_EVENT_TIMEOUT)
break if @stop_good_job_executable.set? || capsule.shutdown?
end

systemd.stop do
Expand Down
5 changes: 3 additions & 2 deletions spec/lib/good_job/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

before do
stub_const 'GoodJob::CLI::RAILS_ENVIRONMENT_RB', File.expand_path("demo/config/environment.rb")
stub_const 'GoodJob::CLI::SHUTDOWN_EVENT_TIMEOUT', 0.1
allow(GoodJob).to receive_messages(configuration: GoodJob::Configuration.new({}), capsule: capsule_mock)
end

Expand All @@ -25,7 +26,7 @@
cli = described_class.new([], {}, {})

cli_thread = Concurrent::Promises.future { cli.start }
sleep_until { cli.instance_variable_get(:@stop_good_job_executable) == false }
sleep_until { cli.instance_variable_get(:@stop_good_job_executable) }

Process.kill 'INT', Process.pid # Send the signal to ourselves

Expand Down Expand Up @@ -76,7 +77,7 @@
cli = described_class.new([], {}, {})

cli_thread = Concurrent::Promises.future { cli.start }
sleep_until { cli.instance_variable_get(:@stop_good_job_executable) == false }
sleep_until { cli.instance_variable_get(:@stop_good_job_executable) }
expect(GoodJob::SystemdService).to have_received(:new)
expect(systemd).to have_received(:start)
expect(systemd).not_to have_received(:stop)
Expand Down

0 comments on commit 2b698b6

Please sign in to comment.