mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-16 23:43:03 +00:00
Critical: seq was an in-memory per-emitter counter (seeded from the log's max) which two concurrent emitters for the same message_id could both read + advance independently, producing duplicate seqs and causing the client dedupe guard to drop one frame per collision. Replace with a per-message Redis INCR on a dedicated `:seq` key — atomic by construction, correct under overlap regardless of how rare overlap is in practice. On Redis unavailability or timeout, emit the frame without a seq and skip the log append; the client treats seq-less frames as "apply directly, no dedupe, no resume" — live streaming survives, resume is the thing that degrades. Warning: adding INCR put two Redis RTTs in the streaming hot path (INCR then XADD), so a slow Redis could stall live tokens. Wrap both calls with asyncio.wait_for(..., timeout=0.5s) and emit anyway on timeout. Under Redis hiccups, frames still reach the user; only resume for those specific frames is lost. Done-TTL shortening also goes through a pipelined wait_for so it can't stall the completion path either. Suggestion: stale reference to the removed `resume-stream:complete` event in a comment. Updated to reference the current single-batch `resume-stream:replay` that serves as both payload and completion signal. |
||
|---|---|---|
| .. | ||
| data | ||
| internal | ||
| migrations | ||
| models | ||
| retrieval | ||
| routers | ||
| socket | ||
| static | ||
| storage | ||
| test | ||
| tools | ||
| utils | ||
| __init__.py | ||
| alembic.ini | ||
| config.py | ||
| constants.py | ||
| env.py | ||
| functions.py | ||
| main.py | ||
| tasks.py | ||