Skip to content

Commit 9cd6bc3

Browse files
ThomasCrambertrosa
authored andcommitted
feat: add on_exit hook
1 parent cb5d230 commit 9cd6bc3

File tree

7 files changed

+42
-28
lines changed

7 files changed

+42
-28
lines changed

lib/solid_queue.rb

+11-21
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,20 @@ module SolidQueue
4141
mattr_accessor :clear_finished_jobs_after, default: 1.day
4242
mattr_accessor :default_concurrency_control_period, default: 3.minutes
4343

44-
delegate :on_start, :on_stop, to: Supervisor
44+
delegate :on_start, :on_stop, :on_exit, to: Supervisor
4545

46-
def on_worker_start(...)
47-
Worker.on_start(...)
48-
end
49-
50-
def on_worker_stop(...)
51-
Worker.on_stop(...)
52-
end
53-
54-
def on_dispatcher_start(...)
55-
Dispatcher.on_start(...)
56-
end
57-
58-
def on_dispatcher_stop(...)
59-
Dispatcher.on_stop(...)
60-
end
46+
[ Dispatcher, Scheduler, Worker ].each do |process|
47+
define_singleton_method(:"on_#{process.name.demodulize.downcase}_start") do |&block|
48+
process.on_start { block.call }
49+
end
6150

62-
def on_scheduler_start(...)
63-
Scheduler.on_start(...)
64-
end
51+
define_singleton_method(:"on_#{process.name.demodulize.downcase}_stop") do |&block|
52+
process.on_stop { block.call }
53+
end
6554

66-
def on_scheduler_stop(...)
67-
Scheduler.on_stop(...)
55+
define_singleton_method(:"on_#{process.name.demodulize.downcase}_exit") do |&block|
56+
process.on_exit { block.call }
57+
end
6858
end
6959

7060
def supervisor?

lib/solid_queue/dispatcher.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class Dispatcher < Processes::Poller
88
after_boot :run_start_hooks
99
after_boot :start_concurrency_maintenance
1010
before_shutdown :stop_concurrency_maintenance
11-
after_shutdown :run_stop_hooks
11+
before_shutdown :run_stop_hooks
12+
after_shutdown :run_exit_hooks
1213

1314
def initialize(**options)
1415
options = options.dup.with_defaults(SolidQueue::Configuration::DISPATCHER_DEFAULTS)

lib/solid_queue/lifecycle_hooks.rb

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module LifecycleHooks
55
extend ActiveSupport::Concern
66

77
included do
8-
mattr_reader :lifecycle_hooks, default: { start: [], stop: [] }
8+
mattr_reader :lifecycle_hooks, default: { start: [], stop: [], exit: [] }
99
end
1010

1111
class_methods do
@@ -17,7 +17,12 @@ def on_stop(&block)
1717
self.lifecycle_hooks[:stop] << block
1818
end
1919

20+
def on_exit(&block)
21+
self.lifecycle_hooks[:exit] << block
22+
end
23+
2024
def clear_hooks
25+
self.lifecycle_hooks[:exit] = []
2126
self.lifecycle_hooks[:start] = []
2227
self.lifecycle_hooks[:stop] = []
2328
end
@@ -32,6 +37,10 @@ def run_stop_hooks
3237
run_hooks_for :stop
3338
end
3439

40+
def run_exit_hooks
41+
run_hooks_for :exit
42+
end
43+
3544
def run_hooks_for(event)
3645
self.class.lifecycle_hooks.fetch(event, []).each do |block|
3746
block.call

lib/solid_queue/scheduler.rb

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Scheduler < Processes::Base
1111
after_boot :schedule_recurring_tasks
1212
before_shutdown :unschedule_recurring_tasks
1313
before_shutdown :run_stop_hooks
14+
after_shutdown :run_exit_hooks
1415

1516
def initialize(recurring_tasks:, **options)
1617
@recurring_schedule = RecurringSchedule.new(recurring_tasks)

lib/solid_queue/supervisor.rb

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class Supervisor < Processes::Base
55
include LifecycleHooks
66
include Maintenance, Signals, Pidfiled
77

8+
after_shutdown :run_exit_hooks
9+
810
class << self
911
def start(**options)
1012
SolidQueue.supervisor = true

lib/solid_queue/worker.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Worker < Processes::Poller
66

77
after_boot :run_start_hooks
88
before_shutdown :run_stop_hooks
9-
9+
after_shutdown :run_exit_hooks
1010

1111
attr_accessor :queues, :pool
1212

test/integration/lifecycle_hooks_test.rb

+15-4
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,40 @@ class LifecycleHooksTest < ActiveSupport::TestCase
88
test "run lifecycle hooks" do
99
SolidQueue.on_start { JobResult.create!(status: :hook_called, value: :start) }
1010
SolidQueue.on_stop { JobResult.create!(status: :hook_called, value: :stop) }
11+
SolidQueue.on_exit { JobResult.create!(status: :hook_called, value: :exit) }
1112

1213
SolidQueue.on_worker_start { JobResult.create!(status: :hook_called, value: :worker_start) }
1314
SolidQueue.on_worker_stop { JobResult.create!(status: :hook_called, value: :worker_stop) }
15+
SolidQueue.on_worker_exit { JobResult.create!(status: :hook_called, value: :worker_exit) }
1416

1517
SolidQueue.on_dispatcher_start { JobResult.create!(status: :hook_called, value: :dispatcher_start) }
1618
SolidQueue.on_dispatcher_stop { JobResult.create!(status: :hook_called, value: :dispatcher_stop) }
19+
SolidQueue.on_dispatcher_exit { JobResult.create!(status: :hook_called, value: :dispatcher_exit) }
1720

1821
SolidQueue.on_scheduler_start { JobResult.create!(status: :hook_called, value: :scheduler_start) }
1922
SolidQueue.on_scheduler_stop { JobResult.create!(status: :hook_called, value: :scheduler_stop) }
23+
SolidQueue.on_scheduler_stop { JobResult.create!(status: :hook_called, value: :scheduler_exit) }
2024

2125
pid = run_supervisor_as_fork(workers: [ { queues: "*" } ], dispatchers: [ { batch_size: 100 } ], skip_recurring: false)
2226
wait_for_registered_processes(4)
2327

2428
terminate_process(pid)
2529
wait_for_registered_processes(0)
2630

31+
2732
results = skip_active_record_query_cache do
28-
assert_equal 8, JobResult.count
29-
JobResult.last(8)
33+
job_results = JobResult.where(status: :hook_called)
34+
assert_equal 12, job_results.count
35+
job_results
3036
end
3137

32-
assert_equal({ "hook_called" => 8 }, results.map(&:status).tally)
33-
assert_equal %w[start stop worker_start worker_stop dispatcher_start dispatcher_stop scheduler_start scheduler_stop].sort, results.map(&:value).sort
38+
assert_equal({ "hook_called" => 12 }, results.map(&:status).tally)
39+
assert_equal %w[
40+
start stop exit
41+
worker_start worker_stop worker_exit
42+
dispatcher_start dispatcher_stop dispatcher_exit
43+
scheduler_start scheduler_stop scheduler_exit
44+
].sort, results.map(&:value).sort
3445
ensure
3546
SolidQueue::Supervisor.clear_hooks
3647
SolidQueue::Worker.clear_hooks

0 commit comments

Comments
 (0)