Skip to content

wip: Periodic refresh of cache warmers (follow-up) - #4125

Draft
FranekKubis wants to merge 5 commits into
Logflare:mainfrom
FranekKubis:fk/o11y-2615/periodic-cache-warmer-refresh
Draft

FranekKubis wants to merge 5 commits into
Logflare:mainfrom
FranekKubis:fk/o11y-2615/periodic-cache-warmer-refresh

Conversation

@FranekKubis

Copy link
Copy Markdown
Contributor

WIP
Closes: O11Y-2615

bblaszkow06 and others added 4 commits October 7, 2026 17:09
Generic code (health check, telemetry, test support, cache busting) called
Cachex directly on every cache module. That breaks as soon as a cache moves to
another backend, e.g. the Nebulex multilevel KeyValues cache in Logflare#4054.

- Logflare.Cache: a behaviour for cache operations (healthy?/0, stats/0,
  reset/0). `use Logflare.Cache` injects overridable Cachex defaults; the
  default implementation module can be swapped with `impl:`.
- `use Logflare.ContextCache` builds on it and makes bust_by/1 a required
  callback with a default primary-key bust. Every bust now goes through the
  cache's bust_by/1; the tuples CacheBuster emits are unchanged.
- The health check, telemetry and test resets call these callbacks instead of
  Cachex.
- Cachex configuration is shared (Logflare.Cache.CachexOps.child_spec/2 with
  named limit/ttl/purge_interval/warmer/compressed options), replacing the
  per-cache child_spec boilerplate and the Utils.cache_* helpers. Every cache
  keeps its current settings.

Behaviour changes:
- /health reports an unhealthy cache as "unhealthy" instead of "no_cache".
- The cachex.<cache>.purge and .stats metrics are removed; Cachex 4 never
  sets them, so they were always 0.
- Cache child specs are typed :supervisor (Cachex starts a supervisor).
- A {Rules, pkey} bust follows Rules.Cache's own `id:` busting instead of
  the generic scan; CacheBuster only sends Rules keyword busts.
- Busting a cache by an unsupported keyword raises ArgumentError.
Process.info(pid, :total_heap_size) returns the heap size in words, but the
cachex.<cache>.total_heap_size metric is declared with unit {:byte, :megabyte},
so the exported value was too small by a factor of the word size (8x on
64-bit). Convert words to bytes with :erlang.system_info(:wordsize) before
emitting it.
…ntation

Logflare.ContextCache still called Cachex directly for the read path
(apply_fun/3, update/4) and for the default primary-key bust.

- ContextCache gains required fetch/2 and update/2 callbacks next to
  bust_by/1. `use Logflare.ContextCache` injects overridable defaults that
  delegate to the `impl:` module (Logflare.Cache.CachexOps by default), and
  apply_fun/3, update/4 and bust_keys/1 only call these callbacks.
- The impl contract is explicit: Logflare.Cache.Ops (healthy?/1, stats/1,
  reset/1) and Logflare.ContextCache.Ops (bust_by/2, fetch/3, update/3).
- The Cachex read path, the primary-key bust and the gossip of cache misses
  move to CachexOps. The `{:cached, value}` wrapper is now private to it.
- ContextCache.fetch/3 and ContextCache.bust_by/2 are removed; callers use
  CachexOps directly.

Still Cachex-only: ContextCache.Gossip's receive side, cache warmers, and
cache modules that call Cachex themselves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@FranekKubis
FranekKubis force-pushed the fk/o11y-2615/periodic-cache-warmer-refresh branch from d7a8c61 to 832dcd1 Compare October 9, 2026 08:40

This branch has not been deployed

No deployments
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.

2 participants