LiveReactIslands.SSR.Cache behaviour (LiveReactIslands v0.1.1)
View SourceBehavior for SSR caching implementations.
This behavior sits between LiveReactIslands.Component and SSR renderer modules,
providing a caching layer to avoid re-rendering islands with identical props and globals.
Usage
Configure a cache module in your application config:
config :live_react_islands,
ssr_renderer: LiveReactIslands.SSR.ViteRenderer,
ssr_cache: LiveReactIslands.SSR.ETSCache,
cache_default_ttl: :timer.minutes(5)Caching is opt-in per component. Components must explicitly specify
ssr_cache: [...] to enable caching.
Cache Key Strategy
Implementations should support configurable cache key behavior via id_in_key option:
id_in_key: false(default) - Hash of{component_name, props, globals}(excludesid, allows cache sharing across instances)id_in_key: true- Hash of{component_name, id, props, globals}(per-instance caching)cache_key_fn- Custom functionfn(name, id, props, globals, opts) -> terms_to_hashfor advanced use cases
TTL Hierarchy
TTL (time-to-live) can be specified at two levels (highest priority first):
- Component config - Configure per-component TTL via
ssr_cache: [ttl: ...]on component - Default - Global default TTL from
:cache_default_ttlin application config
Performance
Implementations should optimize for cache hits:
- Cache hits should avoid GenServer calls (direct ETS read recommended)
- Cache misses should prevent duplicate renders (Winner/Waiter pattern recommended)
- Thundering herd protection (atomic locking via
:ets.insert_new/2)
Summary
Callbacks
Clear all cached entries.
Clear cached entries for a specific component.
Get cached render or render and cache.
Get cache statistics.
Callbacks
@callback clear_cache() :: :ok
Clear all cached entries.
This should remove all cached SSR results, forcing fresh renders on next request.
Returns
:ok- Cache cleared successfully
@callback clear_cache(component_name :: String.t()) :: :ok
Clear cached entries for a specific component.
This should remove only cached results for the specified component name, leaving other components' cache intact.
Parameters
component_name- Name of the component to clear (e.g., "Counter")
Returns
:ok- Component cache cleared successfully
Note
Some implementations may choose to clear the entire cache if selective clearing is not supported or too expensive.
@callback get_or_render( component_name :: String.t(), id :: String.t(), props :: map(), globals :: map(), ssr_strategy :: atom(), renderer_module :: module(), opts :: keyword() ) :: {:ok, String.t()} | {:error, term()}
Get cached render or render and cache.
This is the main entry point for the cache. It should:
- Generate a cache key based on the cache key strategy
- Check if a valid (non-expired) cached result exists
- On cache hit: Return cached HTML immediately
- On cache miss: Render via
renderer_module.render_component/5and cache result
Parameters
component_name- Name of the React component (e.g., "Counter")id- Unique instance ID of the islandprops- Map of props to pass to the componentglobals- Map of global state (includes__versionkey)strategy- SSR strategy (:overwriteor:hydrate_root)renderer_module- Module implementingLiveReactIslands.SSR.Rendererbehavioropts- Keyword list of options::ttl- Override TTL in milliseconds:id_in_key- Include instance ID in cache key (boolean, default: false):cache_key_fn- Custom cache key function (advanced, overridesid_in_key)
Returns
{:ok, html}- Successfully rendered or retrieved from cache{:error, reason}- Rendering failed or cache error
@callback get_stats() :: map()
Get cache statistics.
Returns a map containing cache metrics and information.
Returns
A map with at least:
:size- Number of cached entries:memory- Memory usage in bytes (if available)- Additional implementation-specific metrics