Skip to content

land: lsp-startup-reservations - #965

Merged
ualtinok merged 16 commits into
mainfrom
land/lsp-startup-reservations
Oct 27, 2026
Merged

ualtinok merged 16 commits into
mainfrom
land/lsp-startup-reservations

Conversation

@aft-alfonso

@aft-alfonso aft-alfonso Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Accepted agent delivery; branch-keyed search descriptor included.

RetriggerView in GreptileConfidence Score: 4/5

Fix dropped file notifications during startup before merging.

Findings

  1. P1 File updates disappear during startup ▶

Summary

Language servers now start on background workers and share one reservation per server and workspace.

  • Concurrent callers share one language-server startup per workspace.
  • Diagnostics show when a language server is still starting.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Request server] --> B{Running or reserved?}
  B -->|Running| C[Return ready client]
  B -->|Reserved| D[Return pending or wait unlocked]
  B -->|Neither| E[Reserve startup]
  E --> F[Start and initialize on worker]
  F --> G{Cancelled?}
  G -->|Yes| H[Discard client]
  G -->|No| I[Publish client and wake callers]
Loading

Reviews (1) · Last reviewed commit: "release notes and search-quality descrip..." · Reviewed by Greptile

Comment thread crates/aft/src/lsp/manager.rs
ualtinok and others added 9 commits October 26, 2026 10:46
Locked cold starts return typed pending outcomes instead of spawning inline. All paths share a keyed reservation, completion receipt and cancellation lifecycle; late completions cannot revive a closed manager. Approved pending wording is pinned by exact-text tests. Synchronous test fixtures now wait on the public startup completion without changing their ready/failure expectations. Remote validation follows in a separate job.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Observe the first failure publication before other waiters can drain it, and assert cancellation before the kernel child-exit wait. This makes the release and close controls fail loudly rather than allowing a second poll to mask a missing release or an uncancelled child to hang the proof. Required build-server gates remain unrun after repeated admission refusals; parent requested committed delivery for CI and combined mutation verification.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Retain bounded path-only notifications on each startup reservation, coalescing versions and reading current disk text after installation. Replay uses a client-specific cloned writer outside the manager lock and a cancellation gate; callers receive an error rather than silently losing over-cap paths. Unlocked callers wait through every startup/replay phase and explicit locked diagnostics waits pump worker completions. Preserve request-deadline failure retry semantics. The two capacity-refusal fixtures now call the bounded unlocked request path rather than rerunning an uncached refusal through the generic settling fixture; their behavioral assertions are unchanged. The failing-first notification test observed zero didOpen frames before this repair.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Fix test-module collection initialization reported by the Linux compile. Ensure the cancellation test actually queued a path, clear its one-shot completion hook before replacement startup, and allow the brief planning lock to drain before measuring the paused replay boundary. Always release replay before assertion failures.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Capture each save's write time and check-begin count on the replay worker, then commit those values before releasing deferred server events. This avoids treating a fast analysis completion as if it preceded a delayed replay commit. The replay wait regression also checks event deferral after the client has been installed.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Do not query, settle, or schedule background pulls against a client whose startup replay is pending. Resume pull work only after the reservation releases. Hold deferred notifications from outward drains until their cache/progress effects are applied, deliver them once without reprocessing, and charge deferred input against runtime drain budgets. Explicit diagnostics waits can observe current replay publications without missing their wake-up or consuming outward delivery. No behavioral expectations in the existing CI failure list were rewritten.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Cache and workspace diagnostic requests join already-admitted startup work under the same bounded wait policy, without starting servers or opening files. Immediate pending outcomes remain confined to locked notification/maintenance paths or an exhausted request budget. The paused-replay test covers both a file request and an existing-startup diagnostics join.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok force-pushed the land/lsp-startup-reservations branch from 7981f38 to f7bf4ed Compare October 26, 2026 10:08
ualtinok and others added 3 commits October 26, 2026 11:59
A later request that joins cleanup of an already-expired attempt retries once with its own configuration instead of inheriting the old handshake timeout. Keep cache-only global diagnostics nonblocking. Explicit status reads join the short manager publication rather than returning an empty contention fallback, while publisher try reads remain nonblocking. Bind file waits to accepted notification ownership as well as definition lookup, and continue past inapplicable definitions when finding a live client. No test assertions or wait budgets changed.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Locked notifications no longer spend their handshake time before wait_for_diagnostics is called. Join admitted file startup with the existing handshake bound first, then begin the relative diagnostic observation timeout, restoring the previous effective contract. Absolute-deadline callers are unchanged. Add a channel-controlled regression and read-only failure diagnostics that expose canonical paths, sent URI form, live/pending state and startup exits without changing existing assertions or wait budgets.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
A woken waiter can advance the shared signal to replay before the old worker drops; the old guard then misread the next phase's finished=false as its own failure and cancelled a healthy startup. Disarm ownership before publishing instead. Retain bounded watched-file events through startup/late dynamic registration, preserve explicit/latest event kinds and watcher filtering, and flush via the existing synchronous send paths once ready. The context-based watched fixture collector now releases its manager guard between polls so queued post-write work can run; its 15s budget and assertions are unchanged.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok added this pull request to the merge queue Oct 26, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 27, 2026
ualtinok and others added 4 commits October 27, 2026 11:21
Task: bg_28f9c7c2195afe2f

These changes were saved automatically and have not been reviewed.

Skipped files (left on disk in /Users/ufukaltinok/.local/share/cortexkit/alfonso/worktrees/6d75dd56448a4a9c/2be5fae243ecd1a69e8a0e26ef5da711b9e2a4b8e31fc3ea5735634ccc2a602f/bg_28f9c7c2195afe2f):
"benchmarks/node_modules/" (0 bytes; excluded cache directory (not enumerated))
"node_modules/" (0 bytes; excluded cache directory (not enumerated))
"packages/aft-bridge/node_modules/" (0 bytes; excluded cache directory (not enumerated))
"packages/aft-cli/node_modules/" (0 bytes; excluded cache directory (not enumerated))
"packages/opencode-plugin/node_modules/" (0 bytes; excluded cache directory (not enumerated))
"packages/pi-plugin/node_modules/" (0 bytes; excluded cache directory (not enumerated))
"tests/pi-rpc/node_modules/" (0 bytes; excluded cache directory (not enumerated))

Alfonso-Preserved: retry
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Keep both sides: startup reservations, backlog replay and decoupled
startup/diagnostics waits from this branch, plus main's exact-version
post-edit wait (lsp/fresh_wait.rs) and reader-instance stamping.

Event handling now admits a receipt by reader instance first, then defers
it while its server's start reservation is held, then handles it. Replayed
startup events dropped as retired are not delivered. DrainedLspEvents uses
main's `processed` count, which also counts startup deliveries.

A post-edit wait treats a server whose start is still reserved as pending
rather than exited, and releasing a reservation wakes post-edit waiters, so
an in-flight startup never reads as a finished, clean result.

Test fixtures take main's fresh_wait versions; the empty-wait debug output
this branch had added there is dropped.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok force-pushed the land/lsp-startup-reservations branch from 9a0b2da to 7407d62 Compare October 27, 2026 11:08
@ualtinok
ualtinok added this pull request to the merge queue Oct 27, 2026
@ualtinok
ualtinok removed this pull request from the merge queue due to a manual request Oct 27, 2026
@ualtinok
ualtinok added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 534f89f Oct 27, 2026
91 checks passed
@ualtinok
ualtinok deleted the land/lsp-startup-reservations branch October 27, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant