Jido.Signal.Router.Cache (Jido Signal v2.0.0-rc.1)
View SourceOptional persistent_term caching for Router tries.
This module provides a caching layer for router tries using Erlang's :persistent_term
storage. This is useful for hot-path routing where you want to avoid the overhead of
passing the router struct through function calls.
When to Use
- High-throughput signal routing (10k+ signals/sec)
- Router configuration that changes infrequently
- When you need to share a router across processes without passing the struct
When NOT to Use
- Routers that change frequently (persistent_term has global GC on update)
- Short-lived routers
- When you already have the router struct available
Usage
# Create and cache a router
{:ok, router} = Router.new([{"user.created", MyHandler}], cache_id: :my_router)
# Route using the cached trie (avoids struct lookup)
{:ok, handlers} = Router.Cache.route(:my_router, signal)
# Manually cache an existing router
:ok = Router.Cache.put(:my_router, router)
# Get cached router
{:ok, router} = Router.Cache.get(:my_router)
# Delete cached router
:ok = Router.Cache.delete(:my_router)Multiple Routers
Each router is identified by a unique cache_id (atom or tuple). This allows multiple routers to coexist in the cache:
{:ok, router1} = Router.new(routes1, cache_id: :user_router)
{:ok, router2} = Router.new(routes2, cache_id: :payment_router)Performance Considerations
- Reads from persistent_term are extremely fast (no copying)
- Writes trigger a global garbage collection of all persistent_terms
- Best for routers that are configured at startup and rarely change
Summary
Functions
Checks if a router is cached.
Removes a router from the cache.
Retrieves a cached router trie and wraps it in a Router struct.
Lists all cached router IDs.
Stores a router's trie in persistent_term cache.
Routes a signal using a cached router trie directly.
Updates a cached router with new routes.
Types
Functions
Checks if a router is cached.
Parameters
- cache_id: The identifier to check
Returns
- true if cached, false otherwise
@spec delete(cache_id()) :: :ok
Removes a router from the cache.
Parameters
- cache_id: The identifier used when caching the router
Returns
- :ok (always succeeds, even if key didn't exist)
Example
:ok = Router.Cache.delete(:my_router)
Retrieves a cached router trie and wraps it in a Router struct.
Parameters
- cache_id: The identifier used when caching the router
Returns
{:ok, %Router{}}if found{:error, :not_found}if not cached
Example
{:ok, router} = Router.Cache.get(:my_router)
@spec list_cached() :: [cache_id()]
Lists all cached router IDs.
Note: This iterates all persistent_terms, so use sparingly.
Returns
- List of cache_ids for routers
Stores a router's trie in persistent_term cache.
Parameters
- cache_id: Unique identifier for this cached router (atom or tuple)
- router: The Router struct to cache (or any struct with a
:triefield)
Returns
- :ok
Example
:ok = Router.Cache.put(:my_router, router)
@spec route(cache_id(), Jido.Signal.t()) :: {:ok, [term()]} | {:error, term()}
Routes a signal using a cached router trie directly.
This is the most efficient way to route signals when the router is cached, as it avoids the overhead of reconstructing the Router struct.
Parameters
- cache_id: The identifier of the cached router
- signal: The signal to route
Returns
{:ok, [targets]}- List of matching targets{:error, :not_cached}- Router not in cache{:error, reason}- Routing error
Example
{:ok, handlers} = Router.Cache.route(:my_router, signal)
Updates a cached router with new routes.
This is a convenience function that:
- Gets the cached router (or creates empty)
- Adds the new routes
- Updates the cache
Parameters
- cache_id: The identifier of the cached router
- routes: Routes to add (same format as Router.add/2)
Returns
{:ok, updated_router}on success{:error, reason}on failure