* fix(#6389): remove clear_offline_buffer() teardown blocks that cause data loss on late reconnects Keep the real leak fixes: - unregister_stream_owner() in both streaming.py and gateway_chat.py - AGENT_INSTANCES.pop() in gateway_chat.py The clear_offline_buffer() calls could clear a channel's offline buffer after a late reconnect already fetched the channel but before it subscribed, causing the reconnecting client to lose all buffered events (including stream_end) and hang indefinitely on heartbeats. STREAMS.pop() already releases registry ownership; GC reclaims the buffer once the last outstanding channel reference is dropped, correctly preserving replay for in-flight reconnects. * docs(changelog): stamp #6389 stream-teardown leak fix --------- Co-authored-by: webtecnica <webtecnica@users.noreply.github.com> Co-authored-by: nesquena-hermes <agent@nesquena-hermes> Co-authored-by: nesquena-hermes <agent@webui>
This commit is contained in:
3 files changed
+8
No files matched your search
@@ -19,6 +19,8 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Stream teardown no longer leaks per-stream runtime state on long-running servers.** When a stream ended, its `STREAM_SESSION_OWNERS` owner mapping and (for gateway turns) the `AGENT_INSTANCES` entry were retained, so a high-volume, long-lived server slowly accumulated dead per-stream bookkeeping. Teardown now unregisters the stream owner and drops the gateway agent instance. The offline-frame buffer is deliberately **not** cleared on teardown so a late reconnect can still replay buffered `token`/`done`/`stream_end` frames; buffers remain bounded (8,192 frames) and channels are reclaimed once outstanding reconnect references exit. Thanks @webtecnica. (#6389, #6351)
|
||||
|
||||
- **Japanese UI is fully translated again.** The Japanese (`ja`) locale had drifted to English fallback across recent features (workspace panel, session sharing, extensions gallery, cron sentence-builder, composer, settings, and update flows); it is now refreshed to parity with the current English keys — 180 strings — so Japanese users no longer see a mixed-language UI. Thanks @koshikai. (#6403)
|
||||
|
||||
- **Reloaded tool-call turns render with the same unified Worklog as live turns.** Historical transcripts using ID-linked tool calls (OpenAI-shape `assistant.tool_calls[].id` ↔ `role:tool.tool_call_id`) previously rendered through the legacy renderer after a reload or session switch, so a reloaded turn could look different from how it appeared live. Unambiguous, complete ID-linked turns now hydrate into the unified Assistant Turn Anchor before render, matching the live presentation exactly while failing closed to the existing renderer for any richer or ambiguous case. Thanks @franksong2702. (#6222, #6220)
|
||||
|
||||
@@ -12,6 +12,7 @@ import urllib.request
|
||||
from typing import Any
|
||||
|
||||
from api.config import (
|
||||
AGENT_INSTANCES,
|
||||
CANCEL_FLAGS,
|
||||
PENDING_GOAL_CONTINUATION,
|
||||
STREAM_GOAL_RELATED,
|
||||
@@ -1187,6 +1188,7 @@ def _run_gateway_chat_streaming(
|
||||
logger.debug("Failed to clear gateway stream state", exc_info=True)
|
||||
_cleanup_gateway_pending_mirror(session_id)
|
||||
with STREAMS_LOCK:
|
||||
AGENT_INSTANCES.pop(stream_id, None)
|
||||
CANCEL_FLAGS.pop(stream_id, None)
|
||||
STREAM_GOAL_RELATED.pop(stream_id, None)
|
||||
STREAM_PARTIAL_TEXT.pop(stream_id, None)
|
||||
@@ -1195,4 +1197,5 @@ def _run_gateway_chat_streaming(
|
||||
STREAM_LAST_EVENT_ID.pop(stream_id, None)
|
||||
STREAMS.pop(stream_id, None)
|
||||
_STREAM_RUN_IDS.pop(stream_id, None)
|
||||
unregister_stream_owner(stream_id)
|
||||
unregister_active_run(stream_id)
|
||||
@@ -11001,6 +11001,9 @@ def _run_agent_streaming(
|
||||
STREAM_GOAL_RELATED.pop(stream_id, None) # Clean up goal-related flag (#1932)
|
||||
STREAM_LAST_EVENT_ID.pop(stream_id, None) # Clean up event_id pointer (stage-364)
|
||||
unregister_active_run(stream_id)
|
||||
# Clean up the stream-owner registry so stale stream_id→session_id
|
||||
# mappings do not accumulate over thousands of completed streams (#6351).
|
||||
unregister_stream_owner(stream_id)
|
||||
# NOTE: do NOT discard PENDING_GOAL_CONTINUATION here. The marker
|
||||
# is set by goal_continue (line ~3328) inside the SAME function
|
||||
# call and consumed atomically by `_start_chat_stream_for_session`
|
||||
|
||||
Reference in new issue
Block a user