open-webui/backend/open_webui/socket
Claude d655395b09
fix(stream): unconditional completion, fence timeout, single-batch replay
Three correctness fixes from review:

Critical: in non-Redis deployments the old resume_stream handler
returned early without clearing the client fence, so any call to
requestResumeForMessage would buffer live frames forever and freeze
the UI. Server now always emits exactly one reply (with an empty
envelope list when Redis is disabled or the log is empty), so the
client's fence always clears regardless of backend configuration.

Warning: a lost ack — whether from a transient disconnect between
emit and reply, a server-side exception, a not-yet-registered client
handler, or anything else — would deadlock a message's UI updates
indefinitely. Added:
  - 10s per-message fence timeout that clears the fence and flushes
    buffered frames if no reply arrives
  - disconnect listener that drops all fences on socket loss so the
    reconnect-triggered fresh resume doesn't inherit a stale timer
  - try/finally around replay application so a malformed envelope
    can't skip the fence clear

Suggestion: replay is now a single batch emit instead of N sequential
emits. The server bundles all envelopes (possibly zero) into one
`resume-stream:replay` message; the client applies them in order and
immediately flushes the live-frame fence. Collapses "replay stream
+ completion ack" into a single round-trip, removes the per-envelope
emit loop latency, and simplifies the state machine.
2026-04-14 22:05:22 +00:00
..
main.py fix(stream): unconditional completion, fence timeout, single-batch replay 2026-04-14 22:05:22 +00:00
utils.py refac 2026-03-22 05:48:05 -05:00