Callback or Continuation Registration¶
Registration protocol — instantiates Deferred Fulfillment Placeholder
Hands the placeholder a continuation to run when it resolves — plus a fallback path if it doesn't — so the consumer surrenders its wait instead of parking on it.
Callback or Continuation Registration is the delegating consumer interface: instead of watching a placeholder, the consumer hands over a piece of work — a continuation — and says "run this when you resolve." Its defining move is the surrender of control flow. The consumer does not block, does not hold a live view, and does not come back to ask; it deposits its next step into the placeholder's dependent set and walks away, to be invoked later by whoever resolves the placeholder. Because a registered continuation must cope with either ending, the same registration typically also lodges a fallback path to take if the placeholder fails or is cancelled. This "give the placeholder my next step" posture is what makes it a push mechanism, and what separates it cleanly from an interface where the consumer merely observes.
Example¶
A pharmacy's system fills prescriptions asynchronously. When a patient drops off a script, the system creates a pending "prescription ready" placeholder and the patient registers a callback rather than standing at the counter: "when this resolves, text my phone and unlock my locker code." That instruction is a continuation deposited on the placeholder's dependent set — the patient is now free to leave. Alongside it, the registration lodges a fallback path: "if the drug is out of stock or the insurance is rejected, instead route me to the pharmacist's callback queue and offer the generic substitute." Two branches, both registered up front, both owned by the placeholder.
Hours later the pharmacist finishes the fill and resolves the placeholder. The system invokes the registered continuation — the text goes out, the locker opens — without the patient ever having asked again. Had the fill failed, the same registration's fallback would have fired instead, moving the patient into the substitute flow. The patient never watched a status screen; they delegated their next step and let the placeholder run it at the right moment.
How it works¶
- Register the continuation. Attach the consumer's "next step" to the placeholder's dependent-continuation set. Ownership of the wait transfers to the placeholder; the consumer's own flow ends here.
- Register the alternate branch. Lodge a fallback continuation or value to use if the placeholder resolves to failure, cancellation, or timeout, so the delegated work is total, not just the happy path.
- Invoke on resolution. When the placeholder commits to a terminal state, it fires the matching branch of each registered continuation — success continuations on fulfillment, the fallback path otherwise.
- Retire the registration. After firing (or if the consumer deregisters), the continuation is removed so a resolved placeholder isn't holding dead work.
The mechanism doesn't decide when resolution happens or who may cause it — it only guarantees that a deposited continuation runs at resolution and that a failing branch has somewhere to go.
Tuning parameters¶
- Continuation cardinality — one callback per placeholder or many. Many continuations let independent consumers each attach their own next step; one keeps ordering trivial.
- Fallback richness — whether the alternate branch is a bare default value, a full recovery continuation, or a chain of ordered alternatives. Richer fallbacks handle failure gracefully but grow the registration's surface.
- Invocation context — whether continuations run on the resolver's thread, a dispatcher, or the consumer's original context. Wrong context is a classic source of re-entrancy and deadlock bugs.
- Firing guarantees — at-most-once, exactly-once, or at-least-once invocation of each continuation, and whether a continuation registered after resolution fires immediately or is dropped.
- Ordering — whether multiple continuations fire in registration order, in parallel, or unspecified. Ordered firing is predictable; parallel is faster but hides races between continuations.
When it helps, and when it misleads¶
Its strength is throughput without waiting: a consumer delegates its next step and frees its own resources entirely, which is why this is the backbone of non-blocking, event-driven composition. Expressed formally, it is continuation-passing style[n1] — "what to do next" made an explicit object the callee owns — and lodging the fallback branch alongside the success branch is what keeps a failed placeholder from stranding the delegated work.
Its failure mode is the lost or double-fired continuation: a callback registered against a placeholder that never resolves simply never runs (the work silently evaporates), while a placeholder resolved twice can fire the same continuation twice with real side effects. The classic misuse is deep nesting — callbacks registering callbacks — until error handling and ordering become impossible to follow ("callback hell"). The guarding discipline is to always register a fallback branch (never only the happy path), to lean on the resolver's idempotency guard so a continuation fires exactly once, and to keep continuations shallow, deferring genuine ordered fan-out to a scheduler rather than nesting.
How it implements the components¶
Callback or Continuation Registration fills the delegated-consumer components:
dependent_continuation_set— deposits the consumer's continuation into the placeholder's set of dependents to be invoked at resolution.fallback_value_or_path— registers the alternate branch (value or recovery continuation) to take if the placeholder resolves to a non-success terminal state.
It does not implement progress_signal or promise_visibility_label — surfacing live progress to a consumer who keeps watching is the observe twin, Await or Subscription. Callback registration delegates and departs; the subscriber stays and watches.
Related¶
- Instantiates: Deferred Fulfillment Placeholder — the delegating read-side interface for coordinating around a pending value.
- Consumes: Promise Creation Protocol — a placeholder must exist to register a continuation against.
- Sibling mechanisms: Await or Subscription · Dependency Graph Scheduling · Promise Creation Protocol · Resolution Event Commit · Pending State Polling · Cancellation Propagation · Failure Propagation · Resolved Value Memoization · Timeout Expiration Handler
Editorial Notes¶
Form Classification¶
Form family: Protocol, Workflow & Routine
Rationale: The mechanism registers a next-step continuation and fallback with a placeholder, transfers ownership of the wait, and invokes the appropriate branch on resolution, so its operative form is a delegation protocol.
Nearest alternative: Control, Automation & Runtime — Invocation is automatic, but the mechanism is defined by the reusable registration-transfer-and-callback sequence.
Review outcome: Adjudicated after independent review; high confidence.
Origin Attribution¶
Primary origin: Computer Science & Software Engineering
Origin pattern: Single lineage
Present-day reach: Specialized
Rationale: Programming-language and asynchronous-systems practice registers callbacks or continuations so a consumer yields rather than blocks on unresolved work.
Related originating lineages:
- Mathematics — Continuation-passing semantics formally represents the remaining computation as an explicit function.
Review resolution: Computer science is primary through asynchronous programming, continuations, and promise-resolution handlers. Mathematical logic and continuation semantics form a genuine theoretical lineage, while the operational mechanism remains specialized software practice.
Review outcome: Reconciled after independent review; high confidence.
Notes¶
The dependent-continuation set this mechanism populates is the same structure that propagation and scheduling mechanisms later traverse. Registration owns putting a continuation in; Dependency Graph Scheduling owns ordering the whole set of them across many placeholders. Confusing the two — treating a single callback as if it understood the wider graph — is how ordering bugs sneak in.
[n1] Continuation-passing style expresses "what to do next" as an explicit function (a continuation) handed to the callee, rather than returning to the caller — the theoretical shape a registered callback takes. ↩