Normandy.Agents.Turn.ResumeReaper (normandy v1.3.0)

View Source

Eager-handoff trigger for distributed sessions.

Horde.DynamicSupervisor does NOT redistribute a node's children when that node dies (with members: :auto the dead member is removed from the CRDT, so the reclaim path never fires โ€” see the Phase-7 design ยง7.6). This reaper provides selective eager handoff instead: it monitors cluster nodes and, on :nodedown, restarts the :eager sessions whose server died with the lost node.

A session is reaped when it is (1) :eager (SessionStore.list_resumable/1), (2) not currently registered anywhere (SessionRegistry.whereis/2 == :none), and (3) has a non-terminal persisted turn state. It is restarted as a thin spec under the supervisor, where Turn.Server.init/1 reconstructs config from the persisted template and Turn.resume/1s the in-flight turn โ€” no inbound request.

Run one reaper per node (host supervision tree). Concurrent reapers on multiple survivors are safe: the registry's atomic :via registration means only one start wins; the losers get {:error, {:already_started, _}}, treated as success.

Summary

Functions

Returns a specification to start this module under a supervisor.

Restart every eager, unregistered, non-terminal session under the supervisor. Exposed (not private) so it can be unit-tested without orchestrating real nodes.

Types

opts()

@type opts() :: [
  name: GenServer.name(),
  store: {module(), term()},
  registry: {module(), term()},
  supervisor: term(),
  supervisor_mod: module(),
  template_provider: {module(), term()}
]

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

reap(state)

@spec reap(map()) :: :ok

Restart every eager, unregistered, non-terminal session under the supervisor. Exposed (not private) so it can be unit-tested without orchestrating real nodes.

start_link(opts)

@spec start_link(opts()) :: GenServer.on_start()