I own the named ETS table that backs all GtBridge derived-state caches and invalidate per-module entries when the module recompiles.
Cache consumers (styler call_sites, alias maps, function records, doc
fetches, source paths, module→app lookups) read and write this table
directly via :ets. I do not mediate reads or writes — I only react to
%ModuleEvent{kind: :recompiled} from the EventBroker by
deleting every entry tagged with the affected module.
Cache key shape places the module second so a single match-delete reaches
every entry for a module regardless of the entry's :kind:
{:call_sites, mod, source_hash}
{:alias_map, mod, source_hash}
{:functions, mod, source_hash}
{:docs, mod}
{:source_file, mod}
{:module_app, mod}Public API
start_link/1— supervised starttable/0— name of the ETS table for cache consumerscached/2— read-through cache helper for consumers
Summary
Functions
I read key from the cache table and return the stored value on hit.
On miss I evaluate fun, store the result, and return it.
Returns a specification to start this module under a supervisor.
Functions
I read key from the cache table and return the stored value on hit.
On miss I evaluate fun, store the result, and return it.
Concurrent races between two processes computing the same key are
benign: both produce the same value for a deterministic fun, and the
second insert overwrites the first with identical data.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec start_link(term()) :: GenServer.on_start()
@spec table() :: atom()