Exercises: Real-Time and Streaming Architecture

The most valuable exercise in this chapter is 29.15, and it is a conversation. The rest are code, and code/stream_harness.py runs all of them with no framework, no cluster, and no dependencies — because §29.9's whole claim is that streaming semantics are testable deterministically.

Difficulty: ⭐ warm-up · ⭐⭐ standard · ⭐⭐⭐ deeper. Solutions: daggered (†) and odd-numbered problems are in appendices/answers-to-selected.md.


Part A — Warm-ups ⭐

29.1 † State §29.1's question, and the four answer clusters. How many need streaming?

29.2 Place these on §29.2's spectrum: a fraud check, a daily revenue dashboard, an hourly stock report, a personalization model's feature lookup.

29.3 † What was Lambda's fatal problem? What was Kappa's? What actually replaced them, and which piece of Lambda survives as a technique?

29.4 Define event time, processing time, and a watermark. Why is a watermark always a heuristic?

29.5 † Give the three questions a watermark forces you to answer. Which is not a streaming question at all?

29.6 Why does an idle partition stall the watermark for everything? Why does the job look healthy?

29.7 † Why is "exactly-once delivery" impossible and "exactly-once processing" achievable? Where does the guarantee stop?

29.8 Give the four questions to ask of any stateful streaming job. Which is the one people forget?

29.9 † Why is a join window a business decision rather than a tuning parameter?

29.10 Why is a streaming job deterministically testable? Name the five cases every stateful job's tests should contain.

Part B — Standard ⭐⭐

29.11 Run stream_harness.py --demo idle and read the output. Then set idle_timeout to 300 and explain what changes and why.

29.12 † Reproduce Case Study 1's failure in the harness, then fix it. Report both assertions — the one that captures the bug and the one that captures the fix.

29.13 Measure a real processing_time − event_time distribution from a source you have. Report p50, p99, p99.9, and the maximum. Then say what watermark delay you would choose and what it drops.

29.14 † Using the harness, demonstrate all three of §29.4's late-data policies — drop, correct, side-output — and assert the drop counter in the first.

29.15 — the conversation. Take a "we need real time" request you have heard, or invent a plausible one, and run §29.10's four questions against it. Write down the answers. Report which of the four answer clusters it landed in.

29.16 † Take Chapter 18 §18.9's sessionization and implement it in the harness. Show that the streaming version has the same boundary problem as the batch version, and that the watermark solves it where the overlap read did.

29.17 Build a state-growth demonstration: run an aggregation with and without a TTL for a simulated week and report the state size of each.

29.18 † Write the end-to-end latency SLI from Case Study 1 — max(emission_time − event_time) — for a pipeline you own, batch or streaming. Report it. Is it what you expected?

Part C — Deeper ⭐⭐⭐

29.19 §29.6 says exactly-once ends at the sink's boundary. Enumerate every side effect leaving one of your pipelines — API calls, emails, file drops, webhooks — and say for each whether it carries a deduplication key.

29.20 † Case Study 1 argues that correctness and timeliness are separate properties, and that every one of Chapter 23's twenty-two assertions passed while the job was useless. Design the register's twenty-third entry properly: what does it measure, where does it live, and what threshold?

29.21 Case Study 2's cron offset was a dependency nothing could check. Audit your own scheduler for offsets between jobs, and for each ask whether you can explain the gap in one sentence. Report how many you cannot.

29.22 † §29.5's with_idleness trades a stall for dropped data. Find a job — yours or Kestrel's — where the trade goes the other way, and write the comment that says so, in the form §"The Decision" recommends.

Part D — The Kestrel Platform ⭐⭐⭐

29.23 — Increment 29: one streaming path, deliberately.

(a) Establish which of Kestrel's requirements is genuinely streaming, and write ADR-014 for the four that are not — each with §29.1's question and its answer. That document is the increment's most valuable artifact, because it stops the conversation recurring.

(b) Measure the processing_time − event_time distribution before choosing a watermark. Report p99.9 and the maximum, and state the late-data policy you chose from §29.4's three. Everyone picks 30 seconds. Almost nobody measures. This is the exercise that carries the chapter.

(c) Set with_idleness, with the comment explaining the trade and telling the next person not to copy it blindly.

(d) Make the sink idempotent — a merge on (sku, minute) — rather than transactional, and say why.

(e) Explicit operator UIDs from version one, and a state TTL on any deduplication set.

(f) A freshness assertion on the sink, plus the end-to-end latency SLI. Not consumer lag.

29.24 † Write the five test cases from §29.9 against the job, using the harness. The idle-partition case and the restart-mid-window case are the two that matter — the first encodes Case Study 1, and the second catches missing operator UIDs in a test rather than during a deploy.


Reflection

A. Case Study 1's job was correct and useless; Case Study 2's request was correct and misdirected. Both were resolved by asking what decision the data serves. Where else in this book has that question appeared, and is it the same question?

B. §29.11 lists four reasons streaming is right and four that are not sufficient. Count how many streaming systems you know of that meet one of the first four. If the answer is fewer than you expected, what does that suggest — about the systems, or about the list?