mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
fix(dify_builder): always emit a terminal SSE frame so held version can't go stale
Two paths ended a streaming advance without a terminal `state`/`error` frame, leaving the SSE client stalled to the deadline with a stale held version -> its next action 409s: 1. advance_session published the terminal `state` frame outside the try/finally and unguarded. If the post-advance view projection (get_session_view -> read_graph) or the publish itself raised after a SUCCESSFUL advance, the exception escaped and no terminal frame was sent. Guard it and fall back to a terminal `error` frame. 2. submit_action_stream emitted a terminal `state` frame on settle only for `message`. `update_model` also settles synchronously while bumping the version, so it now emits one too -- otherwise the FE keeps the old version and 409s on its next action. Adds regression tests for both (projection-failure -> error frame; update_model -> state frame). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
87b22412b6
commit
de8a5745ea
4 files changed
+86
-9
No files matched your search
@@ -137,11 +137,24 @@ def advance_session(session_id: str, action_dict: dict, actor_dict: dict, token:
|
||||
if terminal_error is not None:
|
||||
progress_bus.publish(session_id, terminal_error)
|
||||
elif completed is not None:
|
||||
repo, dify, actor = completed
|
||||
view = DifyBuilderService(
|
||||
repo,
|
||||
session_lock,
|
||||
lambda *a, **k: None,
|
||||
get_app_revision_fn=lambda app_id, owner: dify.read_graph(app_id, owner)[1],
|
||||
).get_session_view(session_id, actor)
|
||||
progress_bus.publish(session_id, {"kind": "state", **asdict(view)})
|
||||
# The advance already succeeded and the lock is released; the session is
|
||||
# durable. But the view projection (read_graph) or the publish itself can
|
||||
# still raise -- and if this block let that escape, NO terminal frame
|
||||
# would reach the SSE client, hanging its stream to the deadline with a
|
||||
# stale held version (-> 409 on its next action). Fall back to a terminal
|
||||
# error frame so the client stream always ends.
|
||||
try:
|
||||
repo, dify, actor = completed
|
||||
view = DifyBuilderService(
|
||||
repo,
|
||||
session_lock,
|
||||
lambda *a, **k: None,
|
||||
get_app_revision_fn=lambda app_id, owner: dify.read_graph(app_id, owner)[1],
|
||||
).get_session_view(session_id, actor)
|
||||
progress_bus.publish(session_id, {"kind": "state", **asdict(view)})
|
||||
except Exception:
|
||||
logger.exception("dify_builder terminal state projection/publish failed for session %s", session_id)
|
||||
try:
|
||||
progress_bus.publish(session_id, {"kind": "error", "error": "step failed"})
|
||||
except Exception:
|
||||
logger.exception("dify_builder terminal error frame also failed to publish for session %s", session_id)
|
||||
Reference in new issue
Block a user