Class: RailsPodKit::SolidQueue::SchedulerRunner
- Inherits:
-
Object
- Object
- RailsPodKit::SolidQueue::SchedulerRunner
- Defined in:
- lib/rails_pod_kit/solid_queue/scheduler_runner.rb
Overview
Runs a SolidQueue scheduler — and only the scheduler — as a supervised background thread, so the process running jobs can scale to zero.
Scaling the executor to zero is otherwise a chicken-and-egg problem: with
no executor there is no scheduler, so nothing enqueues the recurring or
scheduled jobs that would wake one. A k8s CronJob can't take over either,
because it can't own dynamic recurring tasks (created and updated at
runtime through SolidQueue.schedule_recurring_task). Moving just the
scheduler onto an always-on process — the web, or the exporter pod —
breaks the cycle: it keeps evaluating the crons and enqueueing, and the
queue depth wakes the executor.
Deliberately not the full supervisor (plugin :solid_queue): that one
forks, and its Puma watchdog takes the host process down when the
supervisor exits — which a transient Postgres disconnect is enough to
cause (rails/solid_queue#512). Here a DB blip at worst kills the scheduler
thread; the supervising timer notices on its next tick and starts a fresh
one, and the host process never notices.
Running it on every replica is safe: enqueues stay exactly-once via the
unique index on solid_queue_recurring_executions (task_key, run_at).
Constant Summary collapse
- DEFAULT_POLLING_INTERVAL =
How often the scheduler re-reads the dynamic tasks from the DB.
5- DEFAULT_SUPERVISION_INTERVAL =
How often we check that the scheduler thread is still alive.
5- SOURCE =
'rails_pod_kit.solid_queue_scheduler'
Instance Method Summary collapse
-
#initialize(polling_interval: DEFAULT_POLLING_INTERVAL, supervision_interval: DEFAULT_SUPERVISION_INTERVAL, recurring_schedule_file: nil) ⇒ SchedulerRunner
constructor
A new instance of SchedulerRunner.
- #running? ⇒ Boolean
-
#start ⇒ Object
Starts the supervisor, which starts the scheduler on its first (immediate) tick and returns without blocking.
-
#stop ⇒ Object
Graceful stop: the supervisor drops its timer before winding the scheduler down (unschedule its timers and deregister the process, instead of leaving a row to expire).
Constructor Details
#initialize(polling_interval: DEFAULT_POLLING_INTERVAL, supervision_interval: DEFAULT_SUPERVISION_INTERVAL, recurring_schedule_file: nil) ⇒ SchedulerRunner
Returns a new instance of SchedulerRunner.
40 41 42 43 44 45 46 |
# File 'lib/rails_pod_kit/solid_queue/scheduler_runner.rb', line 40 def initialize(polling_interval: DEFAULT_POLLING_INTERVAL, supervision_interval: DEFAULT_SUPERVISION_INTERVAL, recurring_schedule_file: nil) @polling_interval = polling_interval @supervision_interval = supervision_interval @recurring_schedule_file = recurring_schedule_file end |
Instance Method Details
#running? ⇒ Boolean
63 64 65 |
# File 'lib/rails_pod_kit/solid_queue/scheduler_runner.rb', line 63 def running? !!@supervisor&.running? end |
#start ⇒ Object
Starts the supervisor, which starts the scheduler on its first (immediate) tick and returns without blocking.
50 51 52 53 |
# File 'lib/rails_pod_kit/solid_queue/scheduler_runner.rb', line 50 def start @supervisor = build_supervisor.start self end |
#stop ⇒ Object
Graceful stop: the supervisor drops its timer before winding the scheduler down (unschedule its timers and deregister the process, instead of leaving a row to expire).
58 59 60 61 |
# File 'lib/rails_pod_kit/solid_queue/scheduler_runner.rb', line 58 def stop @supervisor&.stop @supervisor = nil end |