Skip to content

Source on GitHublib/src/utils/fast_async_queue/

Overview

FastAsyncQueue runs async jobs (AsyncJob) serially in FIFO order—upload queues, sequential APIs, offline sync, etc. Supports manual start() vs auto-start factory, label + JobInfo tracking, in-task retry() with a retry budget, and QueueEvent listeners.

FactoryBehaviorTypical use
FastAsyncQueue()Jobs wait until await start()Batch enqueue, run once
FastAsyncQueue.autoStart()addJob starts processing when idleProcess on arrival, still serial

FastAsyncQueue

Internal linked list; at most one job is running. Calling retry() inside catch marks the head job pendingRetry for another run in the same start() loop. retryTime is the allowed retry count (default 1); -1 means unlimited.

Examples

Manual: enqueue then start().

dart
final queue = FastAsyncQueue();

queue.addJob(
  () => Future.delayed(const Duration(seconds: 1), () => uploadChunk(1)),
  label: 'chunk-1',
  description: 'First chunk',
);
queue.addJob(
  () => Future.delayed(const Duration(seconds: 1), () => uploadChunk(2)),
  label: 'chunk-2',
);

await queue.start(); // FIFO
dart
final queue = FastAsyncQueue.autoStart();

queue.addJob(() => syncProfile());  // runs if idle
queue.addJob(() => syncSettings()); // waits if busy
dart
final queue = FastAsyncQueue.autoStart();

queue.addJob(
  () async {
    try {
      await requestWithTransientError();
    } catch (_) {
      queue.retry(); // within retryTime budget
    }
  },
  label: 'sync-order',
  retryTime: 3,
);

Queue events

Subscribe with addQueueListener for QueueEvent (type, currentQueueSize, jobLabel, timestamp).

dart
final queue = FastAsyncQueue();
queue.addQueueListener((event) {
  debugPrint('$event');
});

Common QueueEventType: queueStart / beforeJob / afterJob / queueEnd, newJobAdded, retryJob / retryLimitReached, queueClosed, queueStopped, violateAddWhenClosed.

API reference


Constructors

dart
final manual = FastAsyncQueue();
final autoRun = FastAsyncQueue.autoStart();
Description
FastAsyncQueue()Jobs wait for start().
FastAsyncQueue.autoStart()Calls start() after addJob when not already running.

FastAsyncQueue.addJob

Appends a job. After close(), silently rejects and emits violateAddWhenClosed; duplicate label throws DuplicatedLabelException. Default label is an ISO8601 timestamp.

dart
queue.addJob(
  () async => doWork(),
  label: 'job-a',
  description: 'Optional note',
  retryTime: 1,
);
ParameterTypeRequiredDescription
jobAsyncJobyesNullary function returning Future.
labelString?noUnique id for getJobInfo and events.
descriptionString?noStored on JobInfo.
retryTimeintnoRetry budget, default 1; -1 = unlimited.

FastAsyncQueue.addJobThrow

Same as addJob, but throws ClosedQueueException when the queue is closed.

dart
queue.addJobThrow(() async => doWork(), label: 'critical');
ParameterTypeRequiredDescription
jobAsyncJobyesTask to run.
labelString?noSame as addJob.
descriptionString?noSame as addJob.
retryTimeintnoSame as addJob.

FastAsyncQueue.start

When non-empty and not already running, drains the queue until empty, stop() interrupts, or the loop clears on stop. No-op when empty, already running, or closed.

dart
await queue.start();
ReturnTypeDescription
Future<void>Completes when this run finishes (or is stopped).

FastAsyncQueue.retry

Call inside the running job (usually in catch). Marks the head job pendingRetry for another run() in this start() loop; exceeds retryTimefailed and retryLimitReached.

dart
try {
  await apiCall();
} catch (_) {
  queue.retry();
}

No parameters.


FastAsyncQueue.stop

Hard stop: clears pending list and _map, resets size, emits queueStopped. Optional callBack runs synchronously at the start.

dart
queue.stop(() => onQueueAborted());
ParameterTypeRequiredDescription
callBackFunction?noRuns when stop begins.

FastAsyncQueue.clear

Calls stop(callBack) and clears job metadata.

dart
queue.clear();
ParameterTypeRequiredDescription
callBackFunction?noPassed to stop.

FastAsyncQueue.close

Blocks further addJob (violateAddWhenClosed or ClosedQueueException); queued and running jobs still finish. Emits queueClosed.

dart
queue.close();

No parameters.


FastAsyncQueue.addQueueListener

Registers one listener (later registration replaces the previous). Receives all QueueEvents.

dart
queue.addQueueListener((QueueEvent event) { /* ... */ });
ParameterTypeRequiredDescription
listenerQueueListeneryesvoid Function(QueueEvent event).

FastAsyncQueue.getJobInfo / list

dart
final info = queue.getJobInfo('chunk-1');
final all = queue.list();
MethodReturnDescription
getJobInfo(label)JobInfoThrows InvalidJobLabelException if missing.
list()List<JobInfo>Snapshot of all tracked jobs.

JobInfo: label, description, state (JobState), retryCount, maxRetry.


Properties

TypeDescription
sizeint (getter)Pending + running count (list length).
isClosedbool (getter)Whether close() was called.

Types and exceptions

JobState

ValueMeaning
pendingEnqueued, waiting
runningExecuting
pendingRetryRetry requested
doneSuccess (about to dequeue)
failedFailed, no more retries (about to dequeue)

Exceptions

TypeWhen
DuplicatedLabelExceptionDuplicate label on addJob
ClosedQueueExceptionaddJobThrow on closed queue
InvalidJobLabelExceptionUnknown label in getJobInfo

Released under the MIT License