Conversation
Search from the most recent end and promote hits within the typed statement array. Keep eviction at lease boundaries and route compiled cache regressions through the native CI planner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (5)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe prepared-statement cache now refreshes entry order on hits, so trimming uses recent access order. New Spinel probes test cache recency, eviction order, and live-cursor preservation. CI planning selects the focused suite for related Spinel and Ruby runtime paths. ChangesSpinel statement-cache LRU
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is identified; the change is mergeable after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Normal request and background processing retain exclusive database-connection ownership, and promotion preserves active statement identity. No supported security bypass was established. Concurrent direct access and interruption behavior remain incompletely verified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
This conflicts with Both PRs claim
I tried the obvious merge — all three in one
The rest rebased cleanly, and the Rust side compiles. I did not push anything. The change itself reads well, by the way — (Not a maintainer, just reviewing.) |
Part of #12, independent of #378.
Spinel's prepared-statement cache retains entries by insertion order: a frequently reused statement can still be trimmed because it was prepared early. Refreshing hits makes replacement follow access order.
Mechanism
DbConn#prepare_cachedsearches from the most-recent end of the existing concreteStmtarray. A hit moves that same entry to the tail in place; an already-most-recent hit needs no array writes. Misses still append. This preserves statement pointers and any live cursor position (cache).The existing trim keeps the last 128 entries at successful lease boundaries. Nothing evicts during prepare, so overflow cannot close an in-use cursor within its lease (trim, lease).
Evidence
Native Lobsters counts, condition
lru-fix-lobsters-counts. Lobstersd771f81f, Spinel62b01c7fc, SQLite 3.45.1, eight pooled connections, capacity 128; 15 warmup sequences, then 100 measured sequences of 106 visits. Hit rate is hits/(hits+prepares), excluding result replay.This rerun uses x2's emitted Lobsters trees and Docker recipe, replacing only the instrumented runtime with this main/branch pair. It exactly reproduces
x2-lobsters-lru's counts: 17.77% fewer prepares OFF and 19.23% fewer ON. Emission inputs retain that condition's three raising compile exclusions; neither runtime includes the separate text-binding repair. Executions and replay counts are unchanged within each bind mode; prepare failures and retained entries after close are zero.The wrapper still exits 1 for the existing
/u/michell_wiegand500: 25/26 representative routes and all 106 verification visits pass. These counts are not timing or untouched-corpus parity claims. The priorx2-lobsters-lrucondition matched 132/132 bodies byte-for-byte in each controlled pair; body equality was not rerun for this counts-only condition.Native warm-hit microbenchmark, condition
lru-fix-warm-hit. The actual base and LRU runtimes, compiled by Spinel at its default-O2, each start with 128 entries. Each sample times 10 millionprepare_cachedlookups after 100,000 warmups; initial promotion is outside the timed loop. There are 21 alternating base/LRU and LRU/base pairs per original entry position, with case order alternated too. Values are nanoseconds per lookup, median [p10–p90].For oldest hits, the paired LRU/base ratio is 1.013 [0.993–1.056]: a small positive point estimate, with overlapping sample ranges, not evidence of zero overhead. MRU-first search removes the long scan for repeated newest hits. These are lookup-only results, excluding stepping and request work. On the 18-core host, load averages (1/5/15 minutes) were 1.91/5.79/11.44 before and 3.48/4.79/10.01 after; one-minute load ranged 1.70–4.02. No worker-owned builds or Docker runs overlapped these samples.
Tests and CI
Three probes compile the real Spinel runtime and check:
Every probe fails on main and passes with the change. Additional mutations that reset hits or trim during prepare fail at their cursor-position and mid-lease assertions (driver, harness).
The suite joins
SPINEL_TESTS; database runtime paths and both test files select it through the existingframework-tests-spinelloop. Planner tests cover those owners and combined selections. The native job remains advisory (planner, workflow).Not covered
Validation
Base: upstream main
65cc85c1e0f2ddd5ac79e2694703589e178f0679, fetched for this branch. macOS arm64; rustc/cargo 1.98.1; Spinel62b01c7fc.SPINEL=/path/to/spinel cargo test --test spinel_stmt_cache_lru -- --ignored: 3 passed.cargo test --lib: 923 passed, 1 ignored, 0 failed.cargo test --no-run: all 440 test executables build; this is build coverage, not full integration execution.python3 -m unittest discover -s tests -p ci_plan_test.py: 35 passed on main and the branch, withTMPDIRset to the worker's canonical path.Across 49 trees / 5,765 files per side, only five Spinel
runtime/db.rbfiles differ; the other 44 trees are byte-identical. The other 35 combinations reject without output on both sides. Current main rejectstiny-blog-uuidfor its undefinedauthenticate_userfilter target.🤖 Generated with Claude Code
Summary by CodeRabbit