docs(#881): faithful token_hex(8) test epoch; document inline shutdown put

PR #896 review follow-up, no behavior change:
- Pinned test EPOCH was 32-bit (token_hex(4)) with a matching comment, but
  production widened to token_hex(8) in 2b3d0687 and the same file already
  pins token_hex(8) at line 401. Widen EPOCH to 16 hex chars + fix the comment.
- Document why the fanout shutdown sentinel put stays inline on the loop: the
  consumer is still alive and drains via non-blocking fan-out, so it returns
  at once; the 1s timeout is a ceiling that never binds (off-loop is reserved
  for the multi-second joins).
This commit is contained in:
Patrick Buckley
2026-07-22 23:43:27 -07:00
parent 52d38f91b1
commit 09a27cfce9
2 changed files with 6 additions and 1 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ from starlette.requests import Request
import turnstone.server as server_mod
EPOCH = "0badf00d" # test-pinned boot epoch (hex, like secrets.token_hex(4))
EPOCH = "0badf00dcafebabe" # test-pinned boot epoch (hex, like secrets.token_hex(8))
def _make_app_state(
+5
View File
@@ -4763,6 +4763,11 @@ async def _lifespan(app: Starlette) -> AsyncGenerator[None, None]:
# off-loop; a thread that outlives its budget is logged and left to
# the daemon flag rather than wedging shutdown.
daemon_stop.set()
# The sentinel put stays inline (unlike the off-loop joins below): the
# fanout consumer is still alive here — it exits only on drawing this
# sentinel — and fans out with non-blocking put_nowait, so the bounded
# queue drains fast and put() returns at once; timeout=1 is a ceiling
# that never binds. Off-loop is reserved for the multi-second joins.
with contextlib.suppress(queue.Full):
app.state.global_queue.put(_FANOUT_SHUTDOWN, timeout=1)
for _t in (fanout, agg_emitter, cleanup):