Skip to content

Batch-level consecutive-failure abort policy #55

Description

@rcbevans

I run batches of jobs that call a paid, occasionally-flaky external API. When that API goes down, the current failure shape is the worst one: every job in the fleet burns its full retry budget — max_attempts with backoff, per job, spread across workers — and then the batch fails anyway. So I pay for N × max_attempts doomed API calls and the batch takes the longest possible time to arrive at the outcome the first handful of failures already predicted.

Retry is strictly per-job, and the batch primitives (BatchHandle.status, wait_for_batch, BatchCompletionStatus) are read-only aggregation. There's no shared "if K jobs in this batch/queue have failed consecutively, stop dispensing and fail the rest" — no counter keyed by batch or queue that the dispatch path consults, no abort-the-remainder primitive.

Today I approximate it from a supervisor process: poll BatchHandle.status, and once failed crosses a threshold, paginate through the remainder and cancel one job at a time. Jobs keep dispatching between polls, and the abort decision lives outside the fleet, so every app that needs this re-implements it (slightly differently, slightly wrong).

What I'd rather declare, roughly:

await client.enqueue_batch(
    items,
    failure_policy=AbortBatchAfter(consecutive_failures=5),
)

or the same idea at the actor_config/queue level — a shared consecutive-failure counter (the leader loop or the dispatch transaction feels like the natural home) that, past the threshold, moves the batch's remaining pending jobs to a terminal state without dispatching them. Snooze/RetryAfter already give per-job control flow; this would be the batch-level analogue.

If this is achievable today through some hook I've overlooked — the reclaim event cursor, a leader-side extension point — I'd love a pointer. Otherwise: does a batch/queue failure policy belong in TaskQ, or do you see this as firmly application-side orchestration?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions