Bier.PrivilegesCache (bier v0.1.0)

Copy Markdown View Source

Per-instance, per-role cache of Bier.Introspection.privileges/3 results for the root OpenAPI document (openapi-mode = follow-privileges).

Entries are stamped with the %Bier.SchemaCache{} snapshot generation, so a schema-cache reload naturally invalidates the whole cache: the first root request per role after a reload misses (generation mismatch), re-queries, and overwrites its entry. That matches PostgREST, whose privilege-derived document content also refreshes on schema reload rather than per request.

The GenServer owns a public ETS table whose tid is published once via :persistent_term — cache hits are direct ETS reads, never a process call. Two concurrent misses for the same role both run the loader and insert idempotently; the loader reads live catalog state, so either result is valid.

A cache fault never fails a request: a missing table (instance without a cache), an unreachable owner, or a table that died mid-request (owner crash/restart racing a stale :persistent_term tid) all degrade fetch/4 to calling loader directly, without attempting to cache — mirroring Bier.JwtCache's handling of the identical "public ETS + persistent_term tid" hazard. terminate/2 erases the :persistent_term entry on a clean shutdown so a restarted owner never leaves the old tid published past that point; the rescue below is what covers the remaining crash→restart window.

Summary

Functions

Returns a specification to start this module under a supervisor.

Returns the cached privileges for role under snapshot generation, running loader (and caching its result) on a miss.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

fetch(name, role, generation, loader)

@spec fetch(Bier.name(), String.t(), reference() | nil, (-> map())) :: map()

Returns the cached privileges for role under snapshot generation, running loader (and caching its result) on a miss.

Falls back to a plain loader.() call when the instance has no cache table (e.g. an instance booted without this child, or direct test calls), or when the table has died out from under a stale published tid (owner mid-restart) — in the latter case nothing is cached.