defmodule Vela.Cache.Supervisor do @moduledoc """ Supervises all processes for a single cache instance. """ use Supervisor def start_link(opts) do config = Keyword.fetch!(opts, :config) Supervisor.start_link(__MODULE__, opts, name: supervisor_name(config.name)) end def supervisor_name(cache_name), do: :"vela_supervisor_#{cache_name}" @impl true def init(opts) do config = Keyword.fetch!(opts, :config) # Initialize topology (which initializes the backend internally) {:ok, topology_state} = config.topology.init(config) # Create L1 tables if near_cache is enabled if config.near_cache, do: Vela.NearCache.create_tables(config.name) # Store in persistent_term for lock-free access by all processes :persistent_term.put({:vela_config, config.name}, config) :persistent_term.put({:vela_topology_state, config.name}, topology_state) children = backend_children(config) ++ [ # TTL Manager runs periodic sweeps for expired entries {Vela.TTL.Manager, name: config.name, config: config}, # Lock Manager serializes fetch locks for stampede protection {Vela.Lock.Manager, name: config.name, config: config}, # Stats Collector tracks hits/misses/writes via atomic counters {Vela.Stats.Collector, name: config.name, config: config} ] ++ distributed_children(config) Supervisor.init(children, strategy: :one_for_one) end defp backend_children(%{backend: Vela.Backend.ETS} = config) do [{Vela.Backend.ETS.TableOwner, name: config.name}] end defp backend_children(_config), do: [] defp distributed_children(%{topology: Vela.Topology.Partitioned} = config) do [{Vela.Distributed.RingManager, name: config.name}] end defp distributed_children(_config), do: [] end