Class: Wurk::Middleware::Expiry
- Inherits:
-
Object
- Object
- Wurk::Middleware::Expiry
- Includes:
- ServerMiddleware
- Defined in:
- lib/wurk/middleware/expiry.rb
Overview
Server middleware. Drops a job whose window has closed before perform
gets a chance to start. Two options open such a window, both stamped onto
the payload as an absolute epoch-float at push (JobUtil#finalize), and the
earlier of the two is the one that counts:
* `expiry`, from Pro's `sidekiq_options expires_in:`. Once `perform` is
invoked it no longer preempts — a long-running job that started in
time finishes.
* `deadline_at`, from `sidekiq_options deadline:`. This one does preempt:
{Timeout} arms the watchdog with whatever is left of it, and the
{Wurk::Job::DeadlineExceeded} that lands in a job still running past
its cutoff unwinds to here, where it takes the same skip path. So a
deadline reaches the same terminal state whether it passed while the
job queued or while it ran — one state to reason about, one counter to
watch, and no retry either way.
The skip path:
* bumps Wurk::Processor::EXPIRED so the heartbeat flushes
`stat:expired` + `stat:expired:YYYY-MM-DD` to Redis, surfacing the
count in Wurk::Stats and the dashboard
* emits `jobs.expired` via Wurk::Metrics::Statsd (no-op when no client
is configured)
* returns without yielding — no exception, so JobRetry treats it as a
clean exit and the processor acks the UoW
* counts as a batch success: because this middleware is registered
AFTER `Wurk::Batch::ServerMiddleware`, returning unwinds back through
batch's `yield`, and batch's `ack_success` still runs on the way out
The expired job is also counted toward PROCESSED — Processor#stats's ensure block always increments PROCESSED, so EXPIRED is an additive subset (executed = processed - failed - expired). Matches Sidekiq Pro.
Spec: docs/target/sidekiq-pro.md §7.
Instance Attribute Summary
Attributes included from ServerMiddleware
Instance Method Summary collapse
-
#call(_job_instance, job, _queue) ⇒ Object
The rescue is scoped to the guarded call rather than the method body: only a job that carries a cutoff can be cut by one, and a job that raises
DeadlineExceededfrom its own code without carrying one has to unwind to JobRetry like any other failure instead of being acked.
Methods included from ServerMiddleware
Instance Method Details
#call(_job_instance, job, _queue) ⇒ Object
The rescue is scoped to the guarded call rather than the method body:
only a job that carries a cutoff can be cut by one, and a job that
raises DeadlineExceeded from its own code without carrying one has to
unwind to JobRetry like any other failure instead of being acked.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/wurk/middleware/expiry.rb', line 50 def call(_job_instance, job, _queue) expiry = job['expiry'] deadline = job['deadline_at'] return yield unless expiry || deadline at = cutoff(expiry, deadline) return yield unless at return drop(job) if ::Time.now.to_f > at begin yield rescue ::Wurk::Job::DeadlineExceeded drop(job) end end |