class

ArrJanitor::Scheduler

Inherits Reference < Object

Runs the configured backends: one worker fiber per backend, each looping and running a scan whenever its backend is due?, then calling schedule_next.

Workers never touch Crystal's Log directly — they emit LogEvents through a shared Reporter/Channel(LogEvent) that the main (calling) fiber drains via LogConsumer.drain, so console output stays ordered across the -Dpreview_mt worker threads.

#run_due is the decomposed, fiber-free scheduling core (iterate the backends once, run each due one) so the scheduling decision is unit-testable without spawning fibers or sleeping.

Constants

SWEEP_INTERVAL = 1.hour

How often the retention-sweep fiber deletes aged processed_downloads rows. Long by design — the audit log is swept on a TTL, not per tick.

TICK = 1.second

How long a worker waits between due-checks (also the shutdown latency ceiling — a worker wakes early when the stop signal arrives).

Constructors

new(backends : Array(Backend), janitor : Janitor = Janitor.new, channel : Channel(LogEvent) = Channel(LogEvent).new(1024), tick : Time::Span = TICK, store : Store | Nil = nil, retention : Time::Span | Nil = nil, sweep_interval : Time::Span = SWEEP_INTERVAL)
Source

Instance methods

channel

The log channel workers feed and the main fiber drains; exposed for tests.

Source
reporter

The channel-backed facade workers log through; exposed for tests.

Source
run

Traps INT/TERM, spawns one worker fiber per backend, then drains the log channel on the calling (main) fiber until shutdown. A helper fiber closes the log channel once every worker has stopped, which lets the drain loop finish and this method return.

Source
run_due(now = Time.local) : Nil

Iterates the backends once, running every due? backend through the janitor and advancing its next_run. The fiber-free core of the worker loop — call it directly in tests to exercise scheduling without fibers.

Source
run_once

Runs a single scan pass over every backend, then returns — the one-shot counterpart to #run. Spawns one worker fiber per backend that runs the backend once (via run_if_due, which runs on a fresh process because next_run is nil) and signals completion; a helper fiber closes the store and log channel once all workers finish, which lets the drain loop end and this method return. No signal traps, no tick loop, and no retention sweep — those are daemon-only.

Source
stop

Signals the workers to stop. Idempotent — safe to call from a signal handler that may fire more than once.

Source
sweep_once

Deletes processed_downloads rows older than the configured retention window and logs how many were removed. A no-op when no store/retention is configured. The fiber-free core of the sweep loop — call it directly in tests to exercise the sweep without spawning a fiber.

Source