ISRPlug (ISRPlug v0.1.1)
View SourceA generic Plug implementing an Incremental Static Regeneration (ISR) pattern.
This plug allows serving cached data (fresh or stale) quickly while triggering non-blocking background tasks to refresh expired data. It's designed to be flexible and reusable in Phoenix applications.
Configuration
The plug is configured via options passed during the plug
call in the router:
plug ISRPlug,
# --- Required ---
fetch_fun: &YourModule.your_fetch_function/1,
apply_fun: &YourModule.your_apply_function/2,
# --- Optional ---
extract_data_fun: &YourModule.your_extract_function/1,
cache_key_fun: &YourModule.your_cache_key_function/1,
ets_table: :my_specific_isr_cache,
cache_ttl_ms: 60_000, # 1 minute
stale_serving_ttl_ms: 3_600_000, # 1 hour
error_handler_fun: &YourModule.your_error_handler/2
See the function documentation for init/1
for details on each option.
Summary
Functions
Processes the connection according to the ISR logic.
Default function for generating a cache key. Returns a fixed atom. Must be public.
Default error handler if synchronous fetch fails. Must be public.
Default function for extracting data. Returns an empty map. Must be public.
Initializes the plug with configuration options.
Functions
Processes the connection according to the ISR logic.
- Extracts data and determines the cache key using configured functions.
- Checks the ETS cache.
- Handles cache hits (fresh or stale).
- If stale, serves stale data and triggers a background refresh task.
- Handles cache misses or expired stale TTL by fetching synchronously.
- If synchronous fetch fails, calls the error handler.
- If data is available (fresh, stale, or newly fetched), applies it using the configured function.
- Returns the (potentially modified) connection.
Default function for generating a cache key. Returns a fixed atom. Must be public.
Default error handler if synchronous fetch fails. Must be public.
Default function for extracting data. Returns an empty map. Must be public.
Initializes the plug with configuration options.
Options
:fetch_fun
(required): A 1-arity function(extracted_data :: any()) -> {:ok, value :: any()} | {:error, reason :: any()}
. Performs the data retrieval.:apply_fun
(required): A 2-arity function(conn :: Plug.Conn.t(), value :: any()) -> Plug.Conn.t()
. Applies the successfully retrievedvalue
(fresh or stale) to the connection. Must return aPlug.Conn.t()
.:extract_data_fun
(optional): A 1-arity function(conn :: Plug.Conn.t()) -> any()
. Extracts necessary data from theconn
to be passed to:fetch_fun
. Defaults tofn _conn -> %{} end
.:cache_key_fun
(optional): A 1-arity function(conn :: Plug.Conn.t()) -> term()
. Generates a unique ETS key based on the connection. Defaults tofn _conn -> :isr_plug_default_key end
. Ensure this generates distinct keys if the fetched data varies based on connection properties.:ets_table
(optional): Atom name for the ETS table. Defaults toisr_plug_cache
. Use distinct names if using the plug multiple times for different purposes.:cache_ttl_ms
(optional): Integer milliseconds for how long data is considered fresh. Defaults to60000
(1 minute).:stale_serving_ttl_ms
(optional): Integer milliseconds after expiry during which stale data can be served while refreshing. Defaults to3600000
(1 hour).:error_handler_fun
(optional): A 2-arity function(conn :: Plug.Conn.t(), reason :: any()) -> Plug.Conn.t()
. Called only when a synchronous fetch fails. Defaults to a function that logs the error and returns the originalconn
.
This function also initializes the specified ETS table if it doesn't already exist.