fix(desktop): signal loopback worker to stop on cancel
Shutting down the callback server stopped the serve thread but left the worker spinning in _xai_wait_for_callback (which polls callback_result) until the timeout. Flag callback_result as cancelled on DELETE so the wait returns promptly and the daemon thread exits — avoids thread buildup on repeated cancel/retry.
This commit is contained in:
@ -4088,6 +4088,15 @@ async def cancel_oauth_session(session_id: str, request: Request):
|
||||
# _xai_wait_for_callback times out (up to 5 min). Free it immediately so
|
||||
# an orphaned listener can't block a subsequent sign-in attempt.
|
||||
if sess.get("flow") == "loopback":
|
||||
# The worker is blocked in _xai_wait_for_callback, which polls
|
||||
# callback_result rather than the server state. Flag the result as
|
||||
# cancelled so that loop returns on its next tick instead of spinning
|
||||
# until the timeout — otherwise repeated cancel/retry piles up daemon
|
||||
# threads. (_cancelled() in the worker then short-circuits before any
|
||||
# persist.)
|
||||
result = sess.get("callback_result")
|
||||
if isinstance(result, dict):
|
||||
result["error"] = result.get("error") or "cancelled"
|
||||
server = sess.get("server")
|
||||
thread = sess.get("thread")
|
||||
try:
|
||||
|
||||
@ -550,6 +550,8 @@ def test_cancel_loopback_session_shuts_down_callback_server():
|
||||
def join(self, timeout=None):
|
||||
shutdown_calls["join"] += 1
|
||||
|
||||
# callback_result is the dict the worker's _xai_wait_for_callback polls.
|
||||
callback_result = {"code": None, "error": None}
|
||||
session_id = "xai-loopback-cancel-shutdown-test"
|
||||
ws._oauth_sessions[session_id] = {
|
||||
"session_id": session_id,
|
||||
@ -559,6 +561,7 @@ def test_cancel_loopback_session_shuts_down_callback_server():
|
||||
"status": "pending",
|
||||
"server": _FakeServer(),
|
||||
"thread": _FakeThread(),
|
||||
"callback_result": callback_result,
|
||||
}
|
||||
|
||||
try:
|
||||
@ -568,6 +571,9 @@ def test_cancel_loopback_session_shuts_down_callback_server():
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert resp.json()["ok"] is True
|
||||
assert shutdown_calls == {"shutdown": 1, "close": 1, "join": 1}
|
||||
# The waiting worker must be signalled so it returns promptly instead
|
||||
# of spinning until the timeout.
|
||||
assert callback_result["error"] == "cancelled"
|
||||
assert session_id not in ws._oauth_sessions
|
||||
finally:
|
||||
ws._oauth_sessions.pop(session_id, None)
|
||||
|
||||
Reference in New Issue
Block a user