backend
module wittgenstein_job_queue.backend
QueueBackend: the target interface a job-queue backend adapter implements.
Adapter pattern (GoF), the same shape wittgenstein-crm-client already
establishes in this codebase (CRMClient + concrete *Adapter classes): one
ABC every concrete backend implements, no registry/factory — a caller imports
and instantiates the concrete backend it wants directly.
Classes
-
QueueBackend — A retry + dead-letter job queue: enqueue, claim exactly once, resolve.
wittgenstein_job_queue.backend.QueueBackend
class QueueBackend()
Bases : ABC
A retry + dead-letter job queue: enqueue, claim exactly once, resolve.
claim_next is the one method every backend must make safe for
competing consumers — N concurrently-running workers calling it against
the same queue must never receive the same job. That guarantee (not
delivery-to-everyone broadcast) is the whole reason this library exists
instead of a Pub/Sub channel.
Methods
-
enqueue — Add a new pending job to the queue.
-
claim_next — Atomically claim the oldest pending job, or
Noneif the queue is empty. -
mark_done — Mark a claimed job as successfully completed.
-
mark_failed — Record a failure.
-
is_drained — True once no job on this queue is still
pending/claimed.
wittgenstein_job_queue.backend.QueueBackend.enqueue
method QueueBackend.enqueue(queue_name: str, payload: dict[str, Any], *, max_attempts: int = 3) → Job
Add a new pending job to the queue.
wittgenstein_job_queue.backend.QueueBackend.claim_next
method QueueBackend.claim_next(queue_name: str, worker_id: str) → Job | None
Atomically claim the oldest pending job, or None if the queue is empty.
wittgenstein_job_queue.backend.QueueBackend.mark_done
method QueueBackend.mark_done(job_id: str) → None
Mark a claimed job as successfully completed.
wittgenstein_job_queue.backend.QueueBackend.mark_failed
method QueueBackend.mark_failed(job_id: str, error: str) → None
Record a failure.
Requeues to pending (so a future claim_next picks it up again)
while attempt_count < max_attempts; once attempts are exhausted the
job moves to dead_letter for manual inspection instead of retrying
forever.
wittgenstein_job_queue.backend.QueueBackend.is_drained
method QueueBackend.is_drained(queue_name: str) → bool
True once no job on this queue is still pending/claimed.
Lets a producer that enqueues work in dependent phases (e.g. "don't enqueue B until every A job has resolved") poll for phase completion without reaching past this interface into the storage layer.