RequestSeal.Discovery.Cache (RequestSeal v0.2.0)

Copy Markdown View Source

Optional caller-started bounded discovery cache; no timers or background refresh.

start_link/1 accepts :name (GenServer name), :max_sources (64, 1–4,096), :max_in_flight (8, 1–256) and :clock (Unix seconds, default system clock). Source identity includes all configuration and trust roots. A full cache returns :cache_overloaded; it never silently evicts revocation tombstones. Pending waiters are bounded to 32 per in-flight capacity slot.

resolve/4 accepts :algorithms (all HTTP algorithms by default), :timeout and :clock. It fetches on expiry/miss, single-flight per source, returns {:ok, Discovery.Resolution} or {:error, Discovery.Error}, and never serves stale keys after failure. Unknown keys in a fresh set do not trigger refetch. In thumbprint mode, source revocations and tombstones reject before fetching. In directory ID mode, they filter computed thumbprints after discovery; a matching directory ID cannot override or become a revocation identity. refresh/2 explicitly fetches even during negative freshness, immediately replacing the old snapshot on success. Failures retain the last observed snapshot without extending its freshness. If it is stale, calls within negative_ttl return :source_unavailable without another connection. CIMD failures are never cached, as required by CIMD-02 Section 5.2. No-store/no-cache snapshots serve only current waiters and are never retained.

remove/3 persistently denies a thumbprint for that source, including across refresh and invalidation. invalidate/2 discards freshness and cancels pending fetches, retaining tombstones. Both return :ok or a bounded error. Removing the source's denial requires a caller-created new cache/configuration. Refresh returns {:ok, KeySet} or a bounded error. Last-waiter cancellation kills the socket-owning fetcher; cache termination also cancels all fetches.

Summary

Functions

Returns a specification to start this module under a supervisor.

Discard a snapshot and pending work, preserving explicit removals.

Explicitly replace a source snapshot on success. Failures retain the last observed snapshot without extending its freshness; stale keys are never served.

Deny a thumbprint persistently for this cache and source.

Resolve a source-selected key ID; misses/expiry fetch under caller limits.

Start the explicitly caller-owned cache.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

invalidate(cache, source)

Discard a snapshot and pending work, preserving explicit removals.

refresh(cache, source)

Explicitly replace a source snapshot on success. Failures retain the last observed snapshot without extending its freshness; stale keys are never served.

remove(cache, source, thumbprint)

Deny a thumbprint persistently for this cache and source.

resolve(cache, source, keyid, opts \\ [])

Resolve a source-selected key ID; misses/expiry fetch under caller limits.

start_link(opts \\ [])

@spec start_link(keyword()) ::
  GenServer.on_start() | {:error, RequestSeal.Discovery.Error.t()}

Start the explicitly caller-owned cache.