fix(api): address review on the event-loop streams

- Per-user SSE cap uses per-connection leases in a sorted set instead of
  a shared INCR/DECR counter with a TTL. A stream that outlived the TTL
  could let the counter expire, then decrement another stream's slot or
  drive the count negative. Leases refresh while a stream sends frames
  and age out when a stream dies without cleanup.
- Shielded cleanup is bounded per step: stream close and on_close in
  ClosingStreamingResponse, unsubscribe and close in AsyncTopic, lease
  release, and the replay-budget check, so a dead Redis connection can't
  hold a request or a graceful shutdown.
- Artifact downloads send an ASCII filename plus an RFC 5987 filename*
  for non-ASCII names, build headers before opening the file, and close
  disk handles off the event loop.
- Type hints and docstrings on the new helpers.
This commit is contained in:
Alex committed 2026-09-14 10:19:59 +01:00
1 parent 54b540ea42
commit e889392eba
17 files changed
+911 -255

No files matched your search

+3 -3
View File
@@ -18,9 +18,9 @@ def topic_name(user_id: str) -> str:
return f"user:{user_id}"
def connection_counter_key(user_id: str) -> str:
"""Redis counter tracking active SSE connections for ``user_id``."""
return f"user:{user_id}:sse_count"
def connection_leases_key(user_id: str) -> str:
"""Redis sorted set of live SSE connection leases for ``user_id``."""
return f"user:{user_id}:sse_leases"
def replay_budget_key(user_id: str) -> str: