durable_queue 0.5.4
durable_queue: ^0.5.4 copied to clipboard
A backend-agnostic persistent task queue for Dart and Flutter with retries, backoff, concurrency control, and recovery.
0.5.4 #
New features, no breaking changes. Storage adapters and packages built for
0.5.0 keep working; adapters must persist the new StoredTask field (see
STORAGE.md).
- Hand-off for work that finishes outside the queue, such as an upload run
by the operating system:
TaskContext.handOff(reference)keeps the task running after its handler returns, without a concurrency slot and across restarts, untilcompleteHandOff(id, reference:)orfailHandOff(id, error, reference:)reports the outcome. Failures follow the type's retry rules.cancelcancels a handed-off task at once. StoredTask.handOffReferenceandStoredTask.isHandedOff.- Startup recovery skips handed-off tasks and still reads running tasks in bounded batches.
- README: hand-off section; links to
durable_queue_workmanageranddurable_queue_transferin the package table, the package diagram, thedrainsection, and the Flutter section.
0.5.3 #
New features, no breaking changes. Storage adapters and packages built for 0.5.0 keep working.
- Scheduled tasks:
enqueue(runAt:)andenqueue(delay:)set the earliest start;enqueueChainapplies it to the first step. WithdependsOn, the later of both conditions decides.TaskEnqueued.runAtreports it. Uses the existingnextAttemptAtfield, so no storage change. drain({timeLimit, waitForScheduled}): start, run what is ready, stop when idle or at the time limit, and return aDrainResult(counts, reason,nextWakeAt). For background jobs with a time budget.retryFailed({group, retryPolicy}): retry every failed task, oldest first, skipping thoseretryrefuses.holdRateLimit(name, key:, duration:)andhasRateLimit(name): make every task in a rate-limit bucket wait, for example after an HTTP 429. Slots reserved before the hold are dropped.- README: "How the packages fit together", a diagram of where each package
plugs into the engine (gates, storage, handlers, lifecycle and UI); sections
for scheduled tasks,
drain,retryFailed, and rate-limit holds.
0.5.2 #
Documentation only. No API or behavior changes.
- README: links to
durable_queue_flutter(app lifecycle and widgets) and uses it in the Flutter section.
0.5.1 #
Documentation only. No API or behavior changes.
- README: links to
durable_queue_connectivity(a ready-made network gate for Flutter) and to the network gate and per-host limit support indurable_queue_dio0.2.0.
0.5.0 #
Rate limits and gates.
- Add rate limits.
register(rateLimit: RateLimit(10, per: ...))limits one task type;addRateLimit(name, limit, types:, keyOf:)adds a limit shared by several types, optionally split into buckets by a key such as an API host. Every attempt counts, retries included. A task that must wait gets a reserved slot and is rescheduled once; other task types keep running. Limits are kept in memory. - Add gates.
addGate(name, gate)adds aQueueGate(for example network access) andregister(requires: {...})makes a task type wait while that gate is closed. Deferred tasks keep their status and attempt count and start as soon as the gate opens. Running tasks are not cancelled when a gate closes.ManualQueueGateis a gate the app opens and closes itself. - Add
register(deferOn:): maps a handler error, such as a connection error, to a required gate. The task is deferred instead of failing, the attempt does not count, and the gate'srecheckis called. - Add
DurableQueue(gateRecheckInterval:, gateErrorDelay:). - Add example
example/rate_limits_and_gates.dart. - README: a table of the
durable_queuepackages; rate limit and gate sections.
Breaking changes #
- New
QueueEventsubclassTaskDeferred(withDeferralReason). Exhaustiveswitchstatements overQueueEventneed a case for it. - No storage contract change. Deferral only moves
nextAttemptAtof apendingorretryScheduledtask, which adapters already honor. Storage adapters written for 0.3 and 0.4 keep working.
0.4.0 #
- Add
retryDelaytoregister: aRetryDelayResolverthat lets an error choose the wait before the next attempt, for example from an HTTPRetry-Afterheader. Returning null keeps theRetryPolicydelay. The attempt still counts towardmaxAttempts; negative waits become zero and long ones are capped atRetryPolicy.maxSchedulableDelay. A resolver that throws falls back to the policy. - Add
TaskContext.whenCancellationRequested, a future that completes when a running task is cancelled (bycancelorcancelGroup), so handlers can abort requests without polling.TaskContexttakes it as a new optional constructor argument. - README:
retryDelay, cancellation signals, and links todurable_queue_sqliteanddurable_queue_dio. The storage contract tests now live in the repository'sdurable_queue_test_supportpackage. - No breaking changes and no storage contract changes. Storage adapters for
0.3.x work unchanged (
durable_queue_sqliteneeds 0.2.0 for its version constraint).
0.3.1 #
Documentation and examples only. No API or behavior changes.
- Add
example/image_upload.dart, a photo-upload flow with selective retries, idempotency and deduplication keys, and tasks that survive a restart. - Add
example/json_file_storage.dart, a file-backed reference adapter that passes the full storage contract suite. - README: problem statement, quick start, architecture diagram, use cases, Flutter integration, storage options, and a capability comparison.
- CONTRIBUTING: discussion, issue, pull request, and adapter guidelines.
0.3.0 #
Orchestration: priorities, dependencies, chains, and groups.
- Add
prioritytoenqueue. Among ready tasks, higher priority starts first; equal priorities keep enqueue order. - Add
dependsOnandonDependencyFailuretoenqueue. A task waits in the newTaskStatus.waitingstate until its dependencies complete. If one fails, is cancelled, or is missing,DependencyFailurePolicycancels the task (the default), fails it, or runs it anyway. Outcomes cascade to further dependents, and the blocking dependency is recorded as aDependencyFailedExceptioninlastFailure. - Add
enqueueChainto store tasks that run one after another. - Add
grouptoenqueue,getTasks(group:), andcancelGroup. retryrestores a task towaitingwhile its dependencies are still active, and refuses while a dependency has not completed.deleteandpurgenever remove a task that a waiting task depends on.- Dependents are written before the task that settles them, so a crash cannot leave a task waiting behind a finished dependency. Startup still uses only bounded queries.
- Add
example/orchestration.dart.
Breaking changes #
TaskStatushas a new value,waiting. Exhaustiveswitchstatements overTaskStatusneed a case for it. It is declared last, so the index of every existing value is unchanged.waitingis active: it blocks deduplication keys and counts forisActive.- Custom
QueueStorageadapters must implementgetWaitingDependentsandgetByGroup, persist the newStoredTaskfields (priority,dependsOn,onDependencyFailure,group), and ordergetNextReadyby priority first (compareReadyTasks). SeeSTORAGE.md. Records stored by earlier versions load with default values, so no data migration is needed.
0.2.0 #
- Add
DurableQueue.retryto re-queue a failed or cancelled task with a fresh attempt budget and an optional replacement retry policy. - Add
DurableQueue.deleteandDurableQueue.purgeso finished tasks no longer accumulate in storage forever.purgefilters by terminal status and age. - Add
DurableQueue.closeandisClosedto stop the worker and close theeventsandstorageErrorsstreams. - Add
TaskStatus.isTerminalandTaskStatus.isActive. - Fix four unresolved dartdoc references and the
TaskStatusstate diagram (due retries move straight torunning). - Add
issue_trackerandtopicsto the pubspec. - No storage contract changes: existing
QueueStorageadapters keep working. - The storage contract for adapter authors now lives in
STORAGE.mdat the package root.
0.1.0 #
- Initial release of the durable task queue.
- Serializable tasks with immutable payload snapshots and isolated execution attempts.
- Indexed in-memory storage, bounded worker queries, and a documented storage contract.
- Constant-delay and exponential retries, jitter, retry predicates, and attempt limits.
- Concurrency limits, deduplication, idempotency metadata, and cancellation.
- Pause, resume, and stop controls.
- Lifecycle events, task queries, and failure metadata.
- Batched startup recovery for interrupted tasks.
- Automatic retries of worker storage operations without rerunning handlers, with a storage error stream and configurable retry delay.
- An injectable clock so retry tests do not wait on real time.