fed8b2eed7
Backend release / release (push) Waiting to run
Bandit Security Scan / bandit_scan (push) Waiting to run
Build and push multi-arch DocsGPT Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Waiting to run
Build and push multi-arch DocsGPT Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Waiting to run
Build and push multi-arch DocsGPT Docker image / manifest (push) Blocked by required conditions
Build and push DocsGPT FE Docker image for development / build (linux/amd64, ubuntu-latest, amd64) (push) Waiting to run
Build and push DocsGPT FE Docker image for development / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Waiting to run
Build and push DocsGPT FE Docker image for development / manifest (push) Blocked by required conditions
Python linting / ruff (push) Waiting to run
Run python tests with pytest / Run tests and count coverage (3.12) (push) Waiting to run
React Widget Build / build (push) Waiting to run
53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
"""Stream/topic key derivations shared by publisher and SSE consumer.
|
|
|
|
Single source of truth for the per-user Redis Streams key and pub/sub
|
|
topic name. Both must agree exactly — a typo here splits the
|
|
publisher's writes from the consumer's reads.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
def stream_key(user_id: str) -> str:
|
|
"""Redis Streams key holding the durable backlog for ``user_id``."""
|
|
return f"user:{user_id}:stream"
|
|
|
|
|
|
def topic_name(user_id: str) -> str:
|
|
"""Redis pub/sub channel used for live fan-out to ``user_id``."""
|
|
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 replay_budget_key(user_id: str) -> str:
|
|
"""Redis counter tracking snapshot replays for ``user_id`` in the
|
|
rolling rate-limit window."""
|
|
return f"user:{user_id}:replay_count"
|
|
|
|
|
|
def stream_id_compare(a: str, b: str) -> int:
|
|
"""Compare two Redis Streams ids. Returns -1, 0, 1 like ``cmp``.
|
|
|
|
Stream ids are ``ms-seq`` strings; comparing as strings would be wrong
|
|
once ``ms`` straddles digit-count boundaries. We parse and compare
|
|
as ``(int, int)`` tuples.
|
|
|
|
Raises ``ValueError`` on malformed input. Callers must pre-validate
|
|
against ``_STREAM_ID_RE`` (or equivalent) — a lex fallback here let
|
|
a malformed id compare lex-greater than a real one and silently pin
|
|
dedup forever.
|
|
"""
|
|
a_ms, _, a_seq = a.partition("-")
|
|
b_ms, _, b_seq = b.partition("-")
|
|
a_tuple = (int(a_ms), int(a_seq) if a_seq else 0)
|
|
b_tuple = (int(b_ms), int(b_seq) if b_seq else 0)
|
|
if a_tuple < b_tuple:
|
|
return -1
|
|
if a_tuple > b_tuple:
|
|
return 1
|
|
return 0
|