mule/runtime/drainer
Synchronous queue draining, mirroring Oban.Queue.Drainer
(queue/drainer.ex): stage scheduled rows when asked, fetch the queue’s
available jobs through the engine, execute each in the CALLING process
with the same executor regular dispatch uses (acks are real — a failure
lands retryable with genuine backoff), and count terminal states.
Two Elixir-inherited details the port makes deliberate choices on:
- The fetch meta is built literally rather than through
init_queue: the port’s init merges the persisted pause/scale overlay (parity §9), which would make draining a runtime-paused queue silently fetch nothing — and “unpausing” viaput_metawould write through to the real overlay. The literal meta reproduces what Basic’sinitgives the Elixir drainer (paused: false). - Elixir’s
Process.put(:mule_draining, true)is not ported: nothing in Oban 2.22’s lib/ reads it (a Pro hook), so there is no behavior to mirror.
Hazards, both true in Elixir too: a worker timeout arms
timer:exit_after in the calling process, so a timed-out drained job
kills the drain caller; and WithRecursion(True) plus scheduled staging
with an always-snoozing worker never terminates — each pass re-stages the
snoozed row and drains it again, changing the counts every time.
Types
pub type DrainOption {
WithLimit(limit: Int)
WithRecursion(recursion: Bool)
WithSafety(safety: Bool)
WithScheduled(scheduled: Bool)
WithScheduledBefore(scheduled_before: timestamp.Timestamp)
}
Constructors
-
WithLimit(limit: Int) -
WithRecursion(recursion: Bool) -
WithSafety(safety: Bool) -
WithScheduled(scheduled: Bool)drainer.ex
with_scheduled: true | false: also promote the queue’s scheduled/retryable rows before fetching. -
WithScheduledBefore(scheduled_before: timestamp.Timestamp)drainer.ex
with_scheduled: %DateTime{}: promote only rows withscheduled_atat or before this.
drainer.ex’s accumulator: drained jobs counted by terminal executor state,
with Exhausted under discard (the :exhausted remap).
pub type DrainResult {
DrainResult(
cancelled: Int,
discard: Int,
failure: Int,
snoozed: Int,
success: Int,
)
}
Constructors
-
DrainResult( cancelled: Int, discard: Int, failure: Int, snoozed: Int, success: Int, )
Values
pub fn drain(
config config: config.Config,
queue queue: String,
options options: List(DrainOption),
) -> Result(DrainResult, engine.EngineError)