C.W.K.
Stream
Lesson 05 of 05 · published

Honest About a Transport You Don't Have

~10 min · entitlements, graceful-degradation, terminal-signal, compatibility

Level 0Open Gate
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"When you can't do the thing, the kind move is to say so clearly — so the client stops knocking on a door that will never open."

A capability the plan doesn't grant

Keep streams live stocks and indices, but there's one thing it deliberately doesn't stream live: forex. The active data plan simply doesn't include a real-time FX entitlement, so a live forex WebSocket would be selling something the backend can't deliver. Rather than fake it or leave a dangling endpoint that errors, Keep does something more thoughtful — it keeps a compatibility route (/ws/forex) that opens no provider connection and immediately sends a terminal daily_rest status. The message means: "FX is daily-REST only here; don't wait for live ticks."

Why the terminal signal matters

Picture an older version of the PWA, still loaded in some tab from before this policy, that expects a live forex socket. If /ws/forex simply didn't exist or errored, that old client would reconnect, fail, back off, reconnect, fail — a quiet retry storm forever, burning battery and hammering the server for a feed that will never come. The terminal daily_rest status ends that loop cleanly: the old client receives a definitive "this is as good as it gets, stop retrying," and settles down to daily REST like a good citizen. A clear "no" is kinder than silence, because silence looks like "try again."

Degrade with a definitive signal, not an error or a void. When you can't provide a capability, the worst responses are a hard error (looks transient, invites retries) and a silent non-response (looks like a slow success, invites waiting). A terminal status that says 'this path is closed, here's the fallback' lets clients — including old ones you no longer control — do the right thing without a human intervening.

Designing for clients you can't update

The deep lesson here is about the clients you don't control. A PWA can sit loaded in a tab for days; you can't force every instance to update the moment you change a policy. So the server has to be graceful toward its own past — it keeps a route that a stale client still expects, and uses it to guide that client into the new behavior. Deleting the endpoint would have been simpler for the code and worse for the fleet of already-loaded clients. Keeping a compatibility path that emits a terminal signal is the design that respects the clients you've already shipped.

Honesty about capability is part of calm. This ties back to the north star from an unexpected angle: a client that retry-storms a dead socket is a client generating anxiety-shaped noise (spinners, reconnect flickers, battery drain). Telling it the honest truth — 'FX is daily-REST, rest easy' — lets even a stale tab settle into the calm resting state instead of thrashing.

Code

A compatibility route that guides old clients home·python
@app.websocket("/ws/forex")
async def forex_ws(ws: WebSocket):
    await ws.accept()
    # The plan grants no live FX entitlement, so open NO provider hub.
    # Instead send a terminal status so any client — including a stale,
    # already-loaded PWA — knows to stop waiting for live ticks and
    # fall back to daily REST cleanly.
    await ws.send_json({"status": "daily_rest", "terminal": True})
    await ws.close()
    # A definitive 'no' ends the retry loop; an error or silence would
    # have invited an endless reconnect storm from old clients.

External links

Exercise

Think of a capability your backend might lose or never have (a feed you're not entitled to, a feature you removed). A client still asks for it. Compare three responses: hard error, silent hang, and a terminal 'closed, use this fallback' signal. For each, describe what a client that you CAN'T update does in response. Which one lets an old, already-deployed client settle down correctly on its own?
Hint
The key constraint is 'clients you can't update.' An error looks retryable, so old clients storm; silence looks slow, so they wait forever. Only a terminal, self-describing signal ('this is closed, here's the fallback') lets a client you shipped months ago do the right thing without you touching it.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.