Conversation
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/vitestThe overall coverage in the branch remains at 90%, unchanged from the branch. Show a code coverage summary of the most impacted files.
Updated |
| return value === OwnershipPhase.opening.toString() || value === OwnershipPhase.running.toString(); | ||
| } | ||
|
|
||
| function isProcessAlive(pid: number): boolean { |
There was a problem hiding this comment.
PID recycling can silently defeat crash-loop recovery.
isProcessAlive(pid) returns true whenever any process currently holds that PID — it can't tell the crashed opener apart from an unrelated process that the OS later assigned the same PID. On a busy machine this is a real collision, not a corner case.
Sequence:
- Opener crashes mid-open, leaving
owner.<pid>.opening. - Before the next startup, the OS recycles
<pid>to some unrelated live process. scanMarkers()counts thatopeningmarker as aliveOwner, soliveOwners === 0is false and the wipe is suppressed.- The user stays stuck in exactly the corruption crash loop this feature exists to break.
writeOwnMarker already persists ${pid}\n${ISO-timestamp} into the marker body, but parseMarker only reads the filename, so the timestamp is currently dead weight. Reading it would close this gap: treat an opening marker older than some threshold (e.g. well beyond any plausible open duration) as a crashed startup regardless of isProcessAlive, since a genuine in-progress open is never that old. That both fixes the recycling case and puts the already-written timestamp to use.
Not blocking, but worth addressing since it's the one path where the safeguard silently no-ops.
There was a problem hiding this comment.
Added a timestamp check so that a marker older than OPENING_MARKER_STALE_MS (5 min) cannot be a live opener, so its age proves a crash no matter what isProcessAlive says
Problem
The LMDB schema cache lives at a single machine-wide path shared by every IDE/language-server process. If opening that database trips a C-level assertion in the native lmdb library, the process is aborted - no JS catch/finally runs. The editor restarts the server, it aborts on the same corrupt data again, and the user is stuck in an infinite startup crash loop with no way for normal try/catch recovery to help.
How it fixes it - a cross-process startup "dirty bit":
owner.<pid>.openingand renames it toowner.<pid>.runningonce the open succeeds; both are removed on clean shutdown.Changes