LiveReactIslands.SSR.ETSCache (LiveReactIslands v0.1.1)
View SourceETS-backed cache implementation for SSR rendering.
Uses the Winner/Waiter pattern for performance and thundering herd protection:
- Cache hits: Direct ETS read (~1-2 microseconds, no GenServer overhead)
- Cache misses: Atomic lock via
:ets.insert_new/2prevents duplicate renders - Winner: First process to acquire lock renders and caches result
- Waiters: Other processes poll ETS for winner's result
- GenServer: Only used for cleanup, stats, and configuration (never in hot path)
Configuration
config :live_react_islands,
ssr_cache: LiveReactIslands.SSR.ETSCache,
cache_default_ttl: :timer.minutes(5),
cache_cleanup_interval: :timer.minutes(1)Opt-In Caching
Caching is opt-in per component. Components must explicitly enable caching:
# Simple opt-in with defaults
defmodule MyApp.Components.ProductCard do
use LiveReactIslands.Component,
component: "ProductCard",
ssr_strategy: :overwrite,
ssr_cache: true # Uses default TTL from config
end
# Custom cache options
defmodule MyApp.Components.ExpensiveChart do
use LiveReactIslands.Component,
component: "ExpensiveChart",
ssr_strategy: :overwrite,
ssr_cache: [ttl: :timer.minutes(10), id_in_key: true]
end
# Not cached (no ssr_cache option)
defmodule MyApp.Components.OtherComponent do
use LiveReactIslands.Component,
component: "OtherComponent",
ssr_strategy: :overwrite
endCache options:
ssr_cache: true # Enable with defaults
ssr_cache: [
ttl: :timer.minutes(10), # Override default TTL
id_in_key: true, # Boolean: include ID in cache key?
ssr_props: %{}, # Override props for SSR (shell caching)
ssr_globals: %{}, # Override globals for SSR (shell caching)
cache_key_fn: &my_key_fn/5 # Custom cache key function (advanced)
]Shell Caching (Skeleton SSR)
You can cache a "shell" or "skeleton" by providing placeholder data for SSR:
defmodule MyApp.Components.UserProfile do
use LiveReactIslands.Component,
component: "UserProfile",
ssr_strategy: :hydrate_root,
ssr_cache: [
ttl: :timer.minutes(10),
ssr_props: %{email: "", name: "Loading..."} # Placeholders for SSR
]
endThe component renders with placeholder data (cached), but the real data is pushed to the client and rendered in a second pass after hydration is completed (to prevent hydration mismatches). This allows caching the HTML structure while supporting user-specific data.
Performance Characteristics
- Cache hit latency: 1-2 microseconds (direct ETS lookup)
- Thundering herd: 500 requests → 1 render + 499 waits
- No GenServer bottleneck on render path
- Atomic locking prevents duplicate renders
- Read concurrency enabled for parallel cache lookups
Summary
Functions
Returns a specification to start this module under a supervisor.
Start the cache GenServer.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Start the cache GenServer.
Options
:default_ttl- Default time-to-live in milliseconds (default: 5 minutes):cleanup_interval- How often to cleanup expired entries (default: 1 minute)
Component-specific cache options are configured on the component itself via the ssr_cache option.