(restore): retry the working-set restore once the cache catches up - #239
Merged
Conversation
restoreWorkingSet() filtered saved sessions against sessionMap and gave up silently on zero candidates, unable to tell "deleted" from "not indexed yet". On a cold cache (schema-migration wipe, manual cache clear, first run against a large project set) sessionMap is still empty when it first runs, so the whole working set was dropped with no error and no toast. The candidate/defer/nothing decision is pulled into a pure function, planWorkingSetRestore() in public/restore-plan.js, loaded as a classic script in the renderer and require()-d directly by tests (same dual-load pattern as public/shortcuts.js) so the fix is exercised for real instead of through a test-side reimplementation. A saved item missing from sessionMap now schedules one retry, fired the next time the existing projects-changed -> loadProjects cycle refreshes sessionMap with real data. The retry is skipped if the user opens a session themselves in the meantime, and mode 'ask' shows a distinct "finishing indexing" notice instead of looking identical to a genuinely empty working set.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #205.
On a launch where the cache is cold, the saved working set did not come back —
no error, no toast, nothing.
restoreWorkingSet()filtered the saved listagainst
sessionMapand returned silently when nothing matched:The filter itself is right — deleted sessions and vanished worktrees are real —
but it cannot tell "this session was deleted" from "this session is not
indexed yet", and treats both as "drop it". The second is a race it loses
whenever the cache is cold: after a schema migration wipes
session_cache,after a manual clear, or on a first run against a large project set.
The saved list was never lost; it lives in
settings.global.openWorkingSet,which the wipe does not touch. It just took a second launch to come back.
What changes
The decision moves to
public/restore-plan.js, a pure function returningrestore,deferornothing. The renderer loads it as a classic script andthe tests
require()it — the dual-mode patternshortcuts.jsalready uses.restoreWorkingSet()keeps only the effects. Ondeferit arms a retry thatfires from the existing
projects-changed→loadProjects()pipeline; no newIPC channel. The retry is consumed at most once, only when the index has
actually produced something, and is cancelled if the user opens a session
themselves in the meantime.
In
askmode a cold-cache skip now shows its own notice, so a pending restoreno longer looks identical to having nothing to restore.
Startup is not blocked waiting for the scan: that is the multi-minute freeze
the v0.0.33–41 perf work removed, and
get-projectssays so in as many words.Verification
The mutation runs on the shipped file, not on a test-side copy: forcing the
defer branch of
planWorkingSetRestoreto never fire turns red the issue'sfirst acceptance test — sessionMap empty at decision time → defer, not drop —
along with five wiring tests, and nothing else.
Stated plainly: the decision is now exercised where it ships, but the wiring
around it — the retry's call sites in
app.js— is still driven through atest-side harness that calls the real module.
app.jscannot be loaded undernode:testwithout prohibitive DOM scaffolding.Residual risk, not fixed: the retry fires when
sessionMapis non-empty, whichmeans "the scan produced something", not "the scan finished". The authoritative
marker is
isInitialScanComplete(), which lives in the main process. On a verylarge tree the retry could in principle fire before every folder is scanned and
still drop a session. Not reproduced, not load-tested.
task check: green, lint 0 errors.