req_managed_agents_host

Durable single-node session host for req_managed_agents.

Turns RMA's per-call ReqManagedAgents.Session into a supervised, crash-survivable, idle-detachable hosted session keyed by a caller-supplied external id. One public function — ReqManagedAgents.Host.send_message/3 — finds, starts, or reattaches the right session, runs it to a terminal, and returns the RMA SessionResult, with the session's upstream identity durably persisted so a BEAM restart resumes the conversation.

Installation

def deps do
[
{:req_managed_agents_host, "~> 0.1.0"}
]
end

Quickstart

Every call needs a :provider (a ReqManagedAgents.Provider), a :handler (a ReqManagedAgents.Handler), and a :store — a {module, opts} pair naming a ReqManagedAgents.Host.Store implementation.

In-memory (ETS)

Fastest option; the locator is gone if the owning process stops. Good for a single long-lived node where losing in-flight session pointers on a crash is acceptable.

{:ok, _pid} = ReqManagedAgents.Host.Store.ETS.start_link(name: :sessions)
store = {ReqManagedAgents.Host.Store.ETS, name: :sessions}
opts = [provider: MyProvider, handler: MyHandler, store: store]
{:ok, %ReqManagedAgents.SessionResult{text: text}} =
ReqManagedAgents.Host.send_message("customer-42", "hello", opts)
# same external id later — even after the SessionServer idle-detached or crashed —
# reattaches the same upstream session instead of minting a new one
{:ok, _result} = ReqManagedAgents.Host.send_message("customer-42", "what's next?", opts)

File-backed (DETS)

Use this when the locator itself must survive a full BEAM restart, not just a process crash — e.g. a deploy or a node bounce. The upstream session id is written to disk on every turn, so re-opening the same file after a restart reattaches exactly where the conversation left off.

{:ok, _pid} =
ReqManagedAgents.Host.Store.DETS.start_link(name: :sessions, file: "/var/data/sessions.dets")
store = {ReqManagedAgents.Host.Store.DETS, name: :sessions, file: "/var/data/sessions.dets"}
opts = [provider: MyProvider, handler: MyHandler, store: store]
{:ok, _result} = ReqManagedAgents.Host.send_message("customer-42", "hello", opts)
# ...BEAM restarts; the same store is reopened from the same file on boot...
{:ok, _result} = ReqManagedAgents.Host.send_message("customer-42", "still there?", opts)

Idle-detach

Sessions idle-detach after idle_timeout_ms (default 300_000ms / 5 minutes) of inactivity — the SessionServer stops, but the Locator row (and thus the upstream session id) survives, so the next send_message/3 for the same external id starts a fresh server and reattaches:

opts = [provider: MyProvider, handler: MyHandler, store: store, idle_timeout_ms: 60_000]

Durability model

License

Apache-2.0. See LICENSE.