Skip to content

Call graph: a briefly busy store reads as busy, not absent - #440

Open
aft-alfonso[bot] wants to merge 5 commits into
mainfrom
land/callgraph-busy-not-absent
Open

aft-alfonso[bot] wants to merge 5 commits into
mainfrom
land/callgraph-busy-not-absent

Conversation

@aft-alfonso

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

Copy link
Copy Markdown

Accepted agent delivery; branch-keyed search descriptor included.


Summary by cubic

Fixes call graph reads during transient SQLite lock contention so a busy store is reported as busy or pending instead of absent, avoiding misleading cold rebuilds and letting maintenance retry.

  • Readonly readiness probes propagate SQLite busy/locked errors as retryable instead of treating them as evidence the store is absent; each caller bounds its probe wait, and an old waiter on a consumed channel cannot retire the retry.
  • A published generation whose reopen probe is busy stays pending; the consumed completion is replaced with an epoch-fenced retry channel so later drains retry the reopen and retain force tokens and pending paths.
  • aft_inspect keeps dead-code results pending (callgraph_building) and count-free across scoped rollups and finalization, even when the store unlocks between probes, and background reconcile keeps unfinished ownership for another attempt.

Written for commit 4a5f596. Summary will update on new commits.

View guided diff Turn on auto-fix

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issues remain.

Summary

The PR keeps a briefly locked call graph distinct from a missing one.

  • Busy call-graph stores stay distinct from missing stores.
  • Published call-graph stores retry opening after SQLite unlocks.
  • Dead-code inspection keeps busy call-graph results pending.

Both earlier, unnumbered findings are addressed in the current code. No new actionable issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Read published call graph] --> B{Database ready?}
  B -->|Yes| C[Install reader]
  B -->|Busy| D[Return busy or pending]
  B -->|Absent| E[Use normal missing-store path]
  F[Build completed] --> B
  D --> G[Keep completion token and pending paths]
  G --> H[Retry with a new receiver identity]
  H --> B
Loading

Reviews (5) · Last reviewed commit: "Move this change's release-note lines to..." · Reviewed by Greptile

@ualtinok ualtinok added the trivial Typo-class change; exempt from the design-approved gate label Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Design gate skipped: the trivial label is applied.

Comment thread crates/aft/src/inspect/job.rs Outdated
Comment thread crates/aft/src/context.rs Outdated
ualtinok added a commit that referenced this pull request Oct 16, 2026
Keep busy dead-code observations Pending and count-free across scoped rollups and command finalization, even if the store unlocks before the second probe. The timeout test intentionally stops expecting Fresh: its pending JSON stays unchanged, but unfinished work must not be classified as completed.

Centralize retry-channel replacement and advance its receiver epoch in inline waits, runtime drain, and CLI warmup. Deterministic real-lock tests cover the inter-probe unlock and two inline waiters; the latter counts one real forced build. Both fixes have restored deliberate-break controls and passing Linux module gates.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok added this pull request to the merge queue Oct 16, 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 16, 2026
ualtinok added a commit that referenced this pull request Oct 16, 2026
Keep busy dead-code observations Pending and count-free across scoped rollups and command finalization, even if the store unlocks before the second probe. The timeout test intentionally stops expecting Fresh: its pending JSON stays unchanged, but unfinished work must not be classified as completed.

Centralize retry-channel replacement and advance its receiver epoch in inline waits, runtime drain, and CLI warmup. Deterministic real-lock tests cover the inter-probe unlock and two inline waiters; the latter counts one real forced build. Both fixes have restored deliberate-break controls and passing Linux module gates.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok force-pushed the land/callgraph-busy-not-absent branch from 68bd7af to 368afb7 Compare October 16, 2026 15:12
@ualtinok
ualtinok added this pull request to the merge queue Oct 16, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 16, 2026
ualtinok added a commit that referenced this pull request Oct 16, 2026
Keep busy dead-code observations Pending and count-free across scoped rollups and command finalization, even if the store unlocks before the second probe. The timeout test intentionally stops expecting Fresh: its pending JSON stays unchanged, but unfinished work must not be classified as completed.

Centralize retry-channel replacement and advance its receiver epoch in inline waits, runtime drain, and CLI warmup. Deterministic real-lock tests cover the inter-probe unlock and two inline waiters; the latter counts one real forced build. Both fixes have restored deliberate-break controls and passing Linux module gates.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
ualtinok added a commit that referenced this pull request Oct 16, 2026
Rebase #440 on #430 (origin/main 90f1792). The failing unwrap is the test's direct open_readonly after the idle-writer channel, not the refresh worker retry. That test seam deliberately holds an exclusive SQLite lock until shutdown even after the foreign writer lease is released. Main already failed fast on that lock but folded its readiness error into None; #440 propagates it as typed transient contention without adding a connection or transaction to this path.

Replace the obsolete absence expectation with a typed contention assertion. Keep the worker's (2, 0) counters (one initial exclusion plus exactly one post-publication open), no fallback checks, pending-path drain, and the post-shutdown new_leaf read. Channel and shutdown synchronization remain deterministic; no sleep or retry is added.

Linux 8-core gates: callgraph_store 232 passed, refresh_worker 41, inspect 377, context 153; the exact regression passed 30/30. cargo check --tests and cargo fmt --all -- --check passed. Deliberately swallowing contention in readonly_readiness failed only the named publication test; the other 40 refresh-worker tests passed, and restoration returned the suite to 41 passes. Both release-note entries survived the rebase.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok force-pushed the land/callgraph-busy-not-absent branch from 368afb7 to 4c148c9 Compare October 16, 2026 16:33
ualtinok and others added 5 commits October 16, 2026 20:36
Propagate existing typed SQLite busy/locked errors through readonly target and readiness probes instead of claiming absence. Bound waiting probes at each call; preserve pending publication reopen events and force tokens in nonwaiting drains. Keep inspect contention count-free and pending, and reuse reconcile Deferred ownership handling.

The existing locked-reader test intentionally changes its None assertion: busy was never evidence of an absent store. Genuine absent/nonwriter and borrow-only wording is now pinned byte-for-byte next to busy retry wording, approved before commit. Real second-connection exclusive locks and seven deliberate-break controls verify the caller classes, including unfinished reconcile ownership. Linux 4-core compile and module gates pass. The one-off native gate is retained only under ignored .cortexkit/scripts/.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Keep busy dead-code observations Pending and count-free across scoped rollups and command finalization, even if the store unlocks before the second probe. The timeout test intentionally stops expecting Fresh: its pending JSON stays unchanged, but unfinished work must not be classified as completed.

Centralize retry-channel replacement and advance its receiver epoch in inline waits, runtime drain, and CLI warmup. Deterministic real-lock tests cover the inter-probe unlock and two inline waiters; the latter counts one real forced build. Both fixes have restored deliberate-break controls and passing Linux module gates.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
Rebase #440 on #430 (origin/main 90f1792). The failing unwrap is the test's direct open_readonly after the idle-writer channel, not the refresh worker retry. That test seam deliberately holds an exclusive SQLite lock until shutdown even after the foreign writer lease is released. Main already failed fast on that lock but folded its readiness error into None; #440 propagates it as typed transient contention without adding a connection or transaction to this path.

Replace the obsolete absence expectation with a typed contention assertion. Keep the worker's (2, 0) counters (one initial exclusion plus exactly one post-publication open), no fallback checks, pending-path drain, and the post-shutdown new_leaf read. Channel and shutdown synchronization remain deterministic; no sleep or retry is added.

Linux 8-core gates: callgraph_store 232 passed, refresh_worker 41, inspect 377, context 153; the exact regression passed 30/30. cargo check --tests and cargo fmt --all -- --check passed. Deliberately swallowing contention in readonly_readiness failed only the named publication test; the other 40 refresh-worker tests passed, and restoration returned the suite to 41 passes. Both release-note entries survived the rebase.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
0.60.0 is published, so its notes stay as shipped.

Co-authored-by: alfonso-aft <289616620+alfonso-aft@users.noreply.github.com>
@ualtinok
ualtinok force-pushed the land/callgraph-busy-not-absent branch from 4c148c9 to 4a5f596 Compare October 16, 2026 18:38
@ualtinok
ualtinok added this pull request to the merge queue Oct 16, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 16, 2026
@ualtinok
ualtinok added this pull request to the merge queue Oct 16, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

trivial Typo-class change; exempt from the design-approved gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant