Anchorage API reference
    Preparing search index...

    A BackgroundTaskManager bound to a hosting DO's Mastra + pubsub, with the boot/alarm lifecycle that makes DO eviction survivable. The hosting DO owns alarm arming (it needs ctx.storage.setAlarm); this class owns the manager wiring, the recovery-firing boot(), and the alarm cleanup() duty.

    The manager itself is PRIVATE. It carries enqueue, registerTaskContext, registerStaticExecutor, resume, and restart — every one of which puts a task body on this deployment WITHOUT passing the fence, because the gate that stops a locked deployment executing is the #gated wrapper this host puts around an executor on the way in. A caller holding the manager could enqueue an unwrapped executor and defeat both. What this class forwards instead is the fence-gated enqueue and the three READS the host route adapter serves.

    Index

    Constructors

    Methods

    • Durable-Object boot wiring, in two phases with different lifetimes.

      REGISTRATION (memoized for the life of the instance): validate the storage domains and re-register the static executors. Nothing here subscribes, claims, or recovers, so it is safe in every fence state — and it must be, because every host boots before routing and the read routes hang off this memo.

      DISPATCHING (fence-gated, re-attempted on every boot until it is admitted): startWorkers() plus manager.init(pubsub). Those two are what make this instance CLAIM work — see #ensureDispatching for why they cannot run behind a closed fence. A refused attempt is deliberately not memoized, so the next boot() from a request or an alarm starts dispatching once the fence reopens, with no operator action.

      A registration that FAILED is memoized only when it can only fail again: the same non-memoized-refusal reasoning #ensureDispatching applies to the fence. A transient storage fault on the first request into a fresh isolate would otherwise be the permanent answer for the life of that isolate — the read routes hang off this memo, so the host would keep 500ing a queue it can now reach, until an eviction nobody can schedule.

      Returns Promise<void>

    • Enqueue a background task through the fence.

      A drain deliberately still ACCEPTS enqueues: the caller is an agent's tool call inside a run the drain is trying to finish, and refusing would fail exactly the runs that are draining. Locked and proof-only refuse, because a row written then is work the migration would have to carry.

      The per-task executor is wrapped with the same gate as the static ones, so a task enqueued while open cannot execute its body after a transition.

      Parameters

      • payload: TaskPayload
      • Optionalcontext: TaskContext

      Returns Promise<EnqueueResult>

    • Tasks matching a filter. The route adapter re-checks scope per row.

      Parameters

      • Optionalfilter: TaskFilter

      Returns Promise<TaskListResult>

    • DO-alarm duty: ensure the DO is booted (a FRESH post-eviction instance recovers HERE, since the alarm is what woke it — see the recovery seam above), then run the manager's TTL cleanup. The hosting DO re-arms the alarm after this returns. Cleanup is core's own cleanup() — the belt to the storage-layer purgeExpiredBackgroundTasks maintenance duty (which needs no live manager); running both is harmless (each only deletes rows past the TTL).

      Returns Promise<void>

    • Lifecycle-event stream, for the route adapter's SSE response.

      Parameters

      • Optionaloptions: {}

      Returns ReadableStream<Record<string, unknown>>