GenServer-based session cache for GUS BIR service.
Caches authenticated sessions to avoid redundant login requests. Sessions are considered valid if they are younger than the configured TTL margin (default: 50 minutes, well under the 60-minute hard limit).
Expiry model
The cache is keyed on the {api_key, environment} pair and holds
at most one entry per key (typically one entry total, since
credentials are read from Application config).
Regular TTL-expired entries are replaced on the next lookup:
:ets.insert/2 on a :set table is an upsert, so a stale row
lives at most until the next call for that credentials pair.
There is no periodic sweep, because with one entry per key there
is nothing to accumulate.
For mid-TTL invalidation — where the server has killed the
session before the local TTL says so, e.g. after the daily 3:20 AM
maintenance window that closes all active sessions — run_with_session/1
detects the failure, evicts the stale entry, and transparently retries
once with a fresh login. Callers do not need to manage this explicitly.
Setup
Add Gusex.SessionCache to your application's supervision tree:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
Gusex.SessionCache,
# ... other children
]
Supervisor.start_link(children, strategy: :one_for_one)
end
endConfiguration
config :gusex, session_ttl: 3000 # seconds, default: 3000 (50 minutes)
Summary
Functions
Returns a specification to start this module under a supervisor.
Runs fun with a cached session, transparently handling expiry and retry.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec run_with_session((Gusex.Types.Session.t() -> {:ok, result} | {:error, term()})) :: {:ok, result} | {:error, term()} when result: term()
Runs fun with a cached session, transparently handling expiry and retry.
On the first attempt, a cached session (or a freshly obtained one if the
cache is empty or stale) is passed to fun. If fun returns a retriable
error — :empty_response (the empirical signal of a session killed by
the server) or an {:http_error, _, _} (possibly transient, possibly
session-related, cheap enough to retry either way) — the cache is evicted
and fun is called once more with a freshly authenticated session. Any
other error is returned as-is.
Returns
{:ok, result}-funreturned{:ok, result}(possibly on the retry){:error, reason}-fun's error, or a login/cache error
@spec start_link(keyword()) :: GenServer.on_start()