2026-05-29 00:15:54 +00:00
|
|
|
"""Static regressions for frontend passive polling hardening."""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
SESSIONS_JS = ROOT / "static" / "sessions.js"
|
|
|
|
|
MESSAGES_JS = ROOT / "static" / "messages.js"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _source(path: Path) -> str:
|
|
|
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_session_list_refreshes_are_coalesced_while_in_flight():
|
|
|
|
|
src = _source(SESSIONS_JS)
|
|
|
|
|
assert "let _renderSessionListInFlight = null" in src
|
|
|
|
|
assert "let _renderSessionListQueuedRequest = null" in src
|
|
|
|
|
assert "async function _runRenderSessionListRefresh" in src
|
|
|
|
|
assert "async function _drainRenderSessionListQueue" in src
|
|
|
|
|
assert "const request={opts:opts||{},gen:++_renderSessionListGen}" in src
|
|
|
|
|
assert "if(_renderSessionListInFlight)" in src
|
|
|
|
|
assert "_renderSessionListQueuedRequest={" in src
|
|
|
|
|
assert "opts:_mergeRenderSessionListOptions" in src
|
|
|
|
|
assert "if (_gen !== _renderSessionListGen) return" in src
|
fix(sessions): always retry sidebar session-list GET on 502/503/504 (#5394)
The sidebar session-list GET had 502/503/504 retry logic, but it was gated
to cold boot only. Once `_sessionListHasLoadedOnce` flipped true, every later
refresh (profile switch, focus/visible/reconnect) shipped no retryStatuses, so
a transient 502 during an nginx->backend restart window failed on the first
attempt and left the sidebar stale until a hard reload (Ctrl+F5).
The session-list GET is idempotent, so retrying it is safe unconditionally.
This moves `retries:1` + `retryStatuses:[502,503,504]` into the base request
options so they apply to every refresh, while keeping the larger boot timeout
(`_SESSION_LIST_BOOT_TIMEOUT_MS`) and `retryTimeouts` boot-only. The api()
wrapper in static/workspace.js already retries when the error status is in
retryStatuses, so no other change is needed.
Extends the existing source-string regression test to assert the retry
options are now always present (declared before the boot-only gate) while the
boot path still carries the timeout + timeout retry.
Reported and root-caused by @weidzhou, who traced the boot-only retry gate.
Co-authored-by: weidzhou <weidzhou@users.noreply.github.com>
2026-07-02 04:21:09 +00:00
|
|
|
assert "const sessionRequestOpts={" in src
|
2026-06-29 11:29:14 +00:00
|
|
|
assert "api('/api/sessions' + sessionListQS,sessionRequestOpts)" in src
|
2026-06-22 05:57:28 +00:00
|
|
|
assert "api('/api/projects' + projectQS,{timeoutToast:false})" in src
|
2026-05-29 00:15:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_approval_and_clarify_fallback_polls_do_not_overlap():
|
|
|
|
|
src = _source(MESSAGES_JS)
|
|
|
|
|
assert "let _approvalFallbackPollInFlight = false" in src
|
|
|
|
|
assert "if (_approvalFallbackPollInFlight) return" in src
|
|
|
|
|
assert "_approvalFallbackPollInFlight = true" in src
|
|
|
|
|
assert "finally { _approvalFallbackPollInFlight = false; }" in src
|
|
|
|
|
assert "_approvalFallbackPollInFlight = false;\n _approvalPollingSessionId = null;" in src
|
|
|
|
|
|
|
|
|
|
assert "let _clarifyFallbackPollInFlight = false" in src
|
|
|
|
|
assert "if (_clarifyFallbackPollInFlight) return" in src
|
|
|
|
|
assert "_clarifyFallbackPollInFlight = true" in src
|
|
|
|
|
assert "finally {\n _clarifyFallbackPollInFlight = false;\n }" in src
|
|
|
|
|
assert "_clarifyFallbackPollInFlight = false;\n _clarifyPollingSessionId = null;" in src
|