respcache

package
v1.19.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package respcache is the v1.11 phase 6 in-memory LRU for hot list responses. Caches `(filter_query, cursor, user_scope) → serialized JSON body + ETag` for 60s; the v1.6 SSE event bus busts the cache on finding.created / finding.resolved / scan.completed events so operators never see stale data after a mutation.

Scope: the findings explorer (/api/v1/findings + /findings/rows) is the only consumer at v1.11.0 — it's the highest-traffic hot path on a busy daemon. /scans + /resources can layer onto the same cache shape in a v1.11.x follow-up if their numbers justify it.

Per-user keying: cache keys include the session user_id so an admin's full-scope filter view doesn't leak to a non-admin hitting the same query string. Token callers share an empty- scope bucket (their bearer-scope already lives in the cursor's filter set + the daemon enforces it server-side).

Index

Constants

View Source
const DefaultSize = 512

DefaultSize caps the cache at 512 distinct (filter, cursor, user) keys. Each entry is a JSON body + ETag string; at the median 50-row response size (~12 KB) the cache footprint stays under 8 MB. The LRU's promote-on-get behavior keeps hot pages resident.

View Source
const DefaultTTL = 60 * time.Second

DefaultTTL is the per-entry expiry. Tighter than the v1.6 ring's 5-min retention so a finding.created event can't race past a stale cache.

Variables

This section is empty.

Functions

func KeyFor

func KeyFor(endpoint, filterQuery, cursor, userID string) string

KeyFor builds a stable cache key from the components callers already have lying around. Hashing keeps the key bounded even when the filter set is large.

Types

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache is the LRU + invalidation hook bundle.

func New

func New(size int, ttl time.Duration) (*Cache, error)

New constructs a Cache. Pass size=0 to use DefaultSize, ttl=0 for DefaultTTL.

func (*Cache) Get

func (c *Cache) Get(key string) (Entry, bool)

Get returns the cached entry + true when the key is present and not expired. Updates hit/miss counters atomically.

func (*Cache) HitRate

func (c *Cache) HitRate() float64

HitRate returns the fraction of Get calls that found a live entry. Returns 0 when the cache hasn't been queried yet.

func (*Cache) Invalidate

func (c *Cache) Invalidate(prefix string) int

Invalidate drops every entry whose key starts with prefix. The LRU exposes Keys() so we scan + remove matches in one pass. O(n) over the cache size; acceptable at DefaultSize=512.

func (*Cache) Purge

func (c *Cache) Purge()

Purge drops every entry — the catastrophic-reset path used when the daemon restarts under leader-election.

func (*Cache) Set

func (c *Cache) Set(key string, body []byte, etag string)

Set stores (or replaces) an entry under key.

func (*Cache) Stats

func (c *Cache) Stats() (hits, misses uint64, size int)

Stats returns the running hit / miss / size counters. Exposed via the daemon's /metrics endpoint + the doctor command.

type Entry

type Entry struct {
	Body     []byte
	ETag     string
	StoredAt time.Time
}

Entry is the cached JSON body + the matching ETag.

type Invalidator

type Invalidator struct {
	// contains filtered or unexported fields
}

Invalidator listens to the SSE bus + drops cache entries for mutating event types.

func NewInvalidator

func NewInvalidator(cache *Cache, prod *events.Producer, logger *slog.Logger) *Invalidator

NewInvalidator wires the listener. Call Run to start consuming; stop by canceling the passed context.

func (*Invalidator) Run

func (in *Invalidator) Run(ctx context.Context)

Run blocks until ctx is canceled. Subscribes to the v1.6 bus + busts the cache on each mutating event.

The prefix map below maps event type → cache key prefix; an event drops every cache entry whose key starts with the matching prefix. "findings:" covers /api/v1/findings + /findings/rows (both keyed via respcache.KeyFor("findings", ...)).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL