Skip to content

Add entry-status and function-entries for cache introspection - #2

Merged
lvh merged 8 commits into
mainfrom
entry-status
May 12, 2026
Merged

Add entry-status and function-entries for cache introspection#2
lvh merged 8 commits into
mainfrom
entry-status

Conversation

@lvh

@lvh lvh commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds entry-status — looks up a single cache entry by cached-fn + args, returning :created-at, :last-hit, :hits, :cold?, :stale? (or nil if no row)
  • Adds function-entries — returns the same fields for every live entry belonging to a cached-fn, plus deserialized :args for table display
  • Both use the same args-cache-key + serialization path the cache already uses internally, so callers don't duplicate that logic or touch the schema directly

Test plan

  • bb test passes (258 assertions, 0 failures)
  • Verify entry-status returns nil before the cached fn is called, a populated map after
  • Verify :cold? / :stale? reflect the configured TTL / max-age correctly
  • Verify function-entries returns one entry per distinct arg set

🤖 Generated with Claude Code

Callers (e.g. Clerk notebooks) need a way to show freshness metadata
for cache entries without taking a raw JDBC dependency or duplicating
the serialization/key logic. entry-status looks up a single entry by
cached-fn + args; function-entries returns all entries for a cached-fn.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e56fdbd99a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/com/latacora/sqlite_cache/core.clj Outdated
- :cold? true if past TTL (evictable if not re-hit soon)
- :stale? true if past max-age (will be evicted unconditionally)"
[cached-fn cache-args]
(let [{:keys [read-conn func-name args-cache-key ttl max-age]} (meta cached-fn)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compute cold/stale flags from each row's TTL values

entry-status (and similarly function-entries) derives ttl/max-age from cached-fn metadata instead of the row being inspected, so :cold? and :stale? can be wrong when the same cache DB contains entries written under older settings (for example after deploying with new TTLs). The cache’s read/expiry logic uses per-row :ttl/:max-age, so these introspection flags can disagree with actual eviction behavior; selecting :ttl and :max-age from the row would keep status reporting accurate.

Useful? React with 👍 / 👎.

lvh and others added 5 commits May 12, 2026 15:53
Instead of reimplementing the cold/stale predicates in pure Clojure,
delegate to the existing maint/cold? and maint/stale? HoneySQL
expressions so SQLite computes them. Also unprivates maint/maybe-inst
which is shared by both namespaces.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also refactors the two fns to share coerce-status-row and
status-base-query helpers, fixes defn- to ^:private per codebase
style, and exposes base-cached-fn in the test harness context so
introspection fns (which read metadata) can be tested cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lvh

lvh commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Code-review note from a consumer:

entry-status looks up via (-> cache-args seq args-cache-key ser/serialize), while the store path in cached does (args-cache-key args) directly (where args is a rest-arg list). For the default :args-cache-key identity + a 0-arity cached fn, this is a mismatch:

  • store: args is (), so the row is keyed on (ser/serialize ())
  • lookup: (seq []) is nil, so the key becomes (ser/serialize nil)

Different serialized bytes ⇒ entry-status returns nil even when a matching row exists.

Doesn't affect my use case — I'm passing (constantly [version]) as :args-cache-key, which ignores its input — but consumers leaning on the default would see misses. Suggest dropping the seq call (or (or (seq cache-args) ())) so empty arg-lists round-trip the same way the store path keys them.

lvh and others added 2 commits May 12, 2026 16:42
Make entry-status variadic (& cache-args) so the args list arrives as
the same ISeq type that cached uses, eliminating the seq conversion
that mapped [] to nil and caused a serialization mismatch for 0-arity
cached functions. Adds a targeted 0-arity test and a generative
property that verifies entry-status finds the row for any arg list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lvh

lvh commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Above comment has been addressed.

@lvh
lvh merged commit f7c7edf into main May 12, 2026
1 check passed
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