Skip to lesson
Exit
Capstone: Full Mock Loop & Self-Exam1 / 2

2 min lesson

The prompt

Rebuild the main list in "The prompt", then say what each item changes.

Step 1 of 2

The promptDrill

Implement a consumer for a streaming token endpoint. It opens an SSE connection to a model provider, yields tokens as they arrive and has to survive the messy reality of a hot path: a slow first byte, a connection that dies mid-stream and a caller who cancels.

  • Stream tokens from a mock provider that emits Server-Sent Events and may stall or drop the connection partway through.
  • Enforce a time-to-first-token timeout and a separate idle timeout between tokens - a stream that goes quiet for 2s is dead, not slow.
  • Support cancellation from the caller so an abandoned editor request stops consuming a provider slot immediately.
  • On a retriable failure before any token has streamed, retry with exponential backoff and full jitter, bounded by a total retry budget.
THE STREAMING CONSUMER, STEP BY STEP

Interactive diagram. Step through it with the Next and Previous controls below, or Tab to a region to read its detail.

diagram: flow

The first-token gate is the line your whole retry policy hangs on.

Learn more

Full explanation

Full explanation

Interview move

Narrate the boundary you will not cross before you write a line: “Once I've streamed a token to the user, I won't blind-retry - that would duplicate output in the editor. Retries only apply to failures before first token.” Stating the idempotency rule up front is the senior signal. It shows you know the failure modes are the problem, not the happy path.

Learn more

References

A reference solve (TypeScript)

A reference solve (TypeScript)One correct shape

Streaming consumer with TTFT + idle timeouts, cancellation and pre-token retry with full jitter.ts
type Token = { text: string };

interface StreamOpts {
  ttftMs: number;      // budget to first token
  idleMs: number;      // max gap between tokens
  maxRetries: number;  // retry budget (pre-first-token only)
  signal?: AbortSignal;
}

async function* streamTokens(
  open: (signal: AbortSignal) => Promise<AsyncIterable<Token>>,
  opts: StreamOpts,
): AsyncGenerator<Token> {
  for (let attempt = 0; ; attempt++) {
    const ctrl = new AbortController();
    const onAbort = () => ctrl.abort();
    opts.signal?.addEventListener("abort", onAbort, { once: true });
    let sawToken = false;
    try {
      const stream = await withTimeout(open(ctrl.signal), opts.ttftMs, ctrl);
      let deadline = opts.idleMs;
      for await (const tok of stream) {
        sawToken = true;
        yield tok;          // user has now seen output
        deadline = opts.idleMs;
      }
      return;               // clean end of stream
    } catch (err) {
      // Once a token streamed, a retry would duplicate output: fail loudly.
      if (sawToken || opts.signal?.aborted) throw err;
      if (attempt >= opts.maxRetries || !retriable(err)) throw err;
      const backoff = Math.random() * Math.min(2 ** attempt * 100, 2_000);
      await sleep(backoff, opts.signal);
    } finally {
      opts.signal?.removeEventListener("abort", onAbort);
    }
  }
}
Watch out

Three places candidates leak: a timeout that never aborts the underlying socket (so the slot is held even after you give up), a retry that fires after a token already streamed and a backoff with no jitter that synchronizes every client into a thundering retry at the same instant. If your solve has any of these, that is your study gap, not a nitpick.

Learn more

Advanced table

Score your own tape

Score your own tapeSelf-rubric

Dimension
Correctness
Pass looks like
Tokens stream in order, clean end terminates, cancel stops consumption
Red flag
Buffers the whole response then returns it
Dimension
Failure handling
Pass looks like
TTFT and idle timeouts both abort the socket; retry only pre-first-token
Red flag
One timeout for everything; retries after partial output
Dimension
Complexity reasoning
Pass looks like
Says backoff is bounded, budget caps total wait, jitter named
Red flag
Unbounded retries or fixed backoff
Dimension
Reviewable code
Pass looks like
Named constants, one responsibility per function, no dead branches
Red flag
Magic numbers, nested try/catch soup
Dimension
Narration
Pass looks like
Explained the idempotency rule and each accept/reject of AI output
Red flag
Pasted a block and could not explain a line

Watch your screen recording with this open. Mark the timestamp of each red flag.