feat(indexer): log and count substate cache refusals, invalidations and evictions - #2527
Open
sdbondi wants to merge 1 commit into
Open
feat(indexer): log and count substate cache refusals, invalidations and evictions#2527sdbondi wants to merge 1 commit into
sdbondi wants to merge 1 commit into
Conversation
sdbondi
force-pushed
the
feat/indexer-cache-observability
branch
from
September 4, 2026 12:11
5512ddf to
c785848
Compare
sdbondi
force-pushed
the
feat/indexer-cache-observability
branch
2 times, most recently
from
September 4, 2026 12:27
680d2ed to
cc8635b
Compare
sdbondi
commented
Sep 4, 2026
sdbondi
left a comment
Member
Author
There was a problem hiding this comment.
Read at cc8635b against development. No blocking findings.
Sound
substate_cache_prunereturns only the eviction delete's row count; the journal delete above it is not folded in, soevictionsmeasures what its help text says (storage_sqlite/writer.rs:684-712).substate_cache_invalidatesums both the versioned and the nonexistence deletes, soinvalidationscounts every retired row rather than every invalidation record (storage_sqlite/writer.rs:641-660).readfetches the entry before consultingserve_watermark, sorefused_staleonly fires when the cache actually had something to serve. A plain miss stays a miss (substate_cache/mod.rs:213-257).- The
Option::inspectpattern for optional metrics matchescached_substate_manager.rs:212. SubstateCache::watermarkstill callswatermarks.getdirectly, which is right: that path decides a fetch watermark, it is not a refusal.
Non-blocking
- The description says the three counters "join the hit/miss pair, registered under
substate_cache_". The hit/miss pair lives undersubstate_scanner_cache_hits/_misses(crates/indexer_lib/src/metrics.rs:14). The struct doc's "a miss rate that climbs alongsiderefused_stale" is correct advice, but someone looking for the miss rate under the same prefix won't find it. Worth a word in the description or the doc comment. serve_watermarktakes the read lock twice:getthenage(substate_cache/mod.rs:174-176). Aconfirmlanding between them yields a log line like "last confirmed 0s ago, over the 60s serve lag". Harmless and rare, but a singleShardWatermarkscall returning the(Option<StateVersion>, Option<Duration>)pair would make the message always consistent.
Nit
- One debug line per refused read means a shard that is unconfirmed at startup logs once per API request until its first sync round lands. Fine at debug; just noting it is not rate limited.
…nd evictions A read refused because the shard's watermark is missing or stale came back as `Ok(None)`, indistinguishable from an empty cache and invisible in the logs, so an indexer whose every read had started costing a committee round trip gave no hint why. The refusal is now logged at debug with the shard, how long ago it was last confirmed (or that it never was since startup) and the serve lag it exceeded. Three counters join the hit/miss pair under `substate_cache_`: `invalidations` (entries retired by the transition stream), `evictions` (entries dropped at the size cap) and `refused_stale` (reads refused on the watermark). `substate_cache_invalidate` and `substate_cache_prune` return the affected row counts to feed them.
sdbondi
force-pushed
the
feat/indexer-cache-observability
branch
from
September 4, 2026 12:42
cc8635b to
c15fce2
Compare
Member
Author
|
Addressed in the amended head: |
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.
Summary
A read refused because the shard's watermark was missing or stale came back as
Ok(None), indistinguishable from an empty cache and invisible in the logs, so an indexer whose every read had started costing a committee round trip gave no hint why (raised twice on #2498).SqliteSubstateCache::readnow logs a refusal at debug with the shard, how long ago it was last confirmed (or that it never was since startup) and the serve lag it exceeded.ShardWatermarks::agesupplies the age.substate_cache_:invalidations— entries retired by a transition from the state sync streamevictions— entries dropped to stay withinsubstate_cache_max_entriesrefused_stale— reads refused on the watermark gatesubstate_cache_invalidateandsubstate_cache_prunereturn the affected row counts to feed them; the metrics struct is shared between the cache and the sync worker.Phase 3 items 2 and 3 from the indexer cache plan.