docs(#4671): clarify dead-assignment backstop + add four-guard contract comment (Opus polish)
Opus ship-gate non-blocking observations (no MUST-FIX), applied to lower future-maintainer risk on the crown-jewel profile-switch surface: - clarified the belt-and-suspenders _sessionListSkeletonActive=false at the real-paint site - added a FOUR-GUARD CONTRACT doc-comment at the top of switchToProfile naming the four interacting state pieces (embargo / invalidation / skeleton-flag / _wsTreeGen + _switchGen) so a future edit touching one without the others doesn't silently reopen a window. Co-authored-by: rodboev <rodboev@users.noreply.github.com>
This commit is contained in:
1 parent
710f2c6934
commit
749f95d01c
2 files changed
+25
-1
No files matched your search
@@ -5897,6 +5897,25 @@ window.addEventListener('resize',()=>{
|
||||
});
|
||||
|
||||
async function switchToProfile(name) {
|
||||
// ── #4671 profile-switch loading-skeleton — FOUR-GUARD CONTRACT ───────────────
|
||||
// The skeleton must never be clobbered by the OLD profile's content and must never
|
||||
// strand. Four interacting pieces of state cooperate; an edit touching one without
|
||||
// the others can silently reopen a clobber/strand window, so keep them in sync:
|
||||
// 1. _profileSwitchListEmbargo (sessions.js) — set BEFORE the skeleton, drops EVERY
|
||||
// session-list payload (success + fetch-failure) during the switch window; lifted
|
||||
// immediately before the switch-owned renderSessionList(), on failure-restore, and
|
||||
// in the _switchGen-guarded finally. Closes the "render that STARTS mid-switch,
|
||||
// before the new-profile cookie is set, fetched the old profile" window.
|
||||
// 2. _invalidateSessionListRenders() (sessions.js) — bumps _renderSessionListGen +
|
||||
// clears pending/queued at switch start; discards renders already in flight/queued.
|
||||
// 3. _sessionListSkeletonActive (sessions.js) — renderSessionListFromCache() bails
|
||||
// while true; cleared ONLY on fresh data (_applySessionListPayload), fetch-error,
|
||||
// and failure-restore — so a bail can't strand the skeleton.
|
||||
// 4. _wsTreeGen (workspace.js) — bumped UNCONDITIONALLY here (incl. panel-closed, since
|
||||
// loadDir('.') still runs); loadDir rejects stale /api/list whose gen is superseded.
|
||||
// Plus _profileSwitchGeneration / _switchGen — guards superseded switches so a slower
|
||||
// earlier switch can't clobber a newer one's skeleton/embargo.
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// No-op self-switch guard: bail before showing any loading skeleton if we're
|
||||
// already on this profile, so paths like activateCurrentProfile() (which
|
||||
// doesn't pre-check) can't flash a skeleton→restore for a click that changes
|
||||
|
||||
+6
-1
@@ -5534,7 +5534,12 @@ function renderSessionListFromCache(){
|
||||
const committedSwipeReflowDelay=Math.max(0,committedSwipeDuration-SESSION_SWIPE_REFLOW_LEAD_MS);
|
||||
const listScrollTopBeforeRender=list.scrollTop||0;
|
||||
list.innerHTML='';
|
||||
// A real render has arrived — the skeleton (if any) is now replaced. (#4662)
|
||||
// #4671: belt-and-suspenders. The authoritative skeleton-clear happens in
|
||||
// _applySessionListPayload (once fresh data is in hand) BEFORE this function is
|
||||
// reached, and the guard at the top of renderSessionListFromCache bails while the
|
||||
// flag is still true — so by the time we paint here the flag is already false. Keep
|
||||
// this assignment as a defensive backstop for any future non-switch caller that
|
||||
// reaches a real paint with the flag somehow still set.
|
||||
_sessionListSkeletonActive=false;
|
||||
// Batch select bar (when in select mode)
|
||||
if(_sessionSelectMode){
|
||||
|
||||
Reference in new issue
Block a user