Normandy.Agents.Turn.Session (normandy v1.2.0)

View Source

Router in front of Turn.Server. Resolves session_id to a live pid via the SessionRegistry; on a miss, rehydrates turn state + conversation memory from the SessionStore and starts a Turn.Server under Turn.Supervisor with the caller-supplied config (the store never holds config/credentials).

Tier-2 thin start (when opts[:template_provider] is set)

The caller supplies a full :config AND a :template_provider. On first start, rehydrate_and_start/1 persists a secret-free ConfigTemplate derived from the config, then launches Turn.Server with thin opts (no :config). The server reconstructs the full config node-locally from the stored template + supplement + credential token. On subsequent starts (after passivation), the server finds the persisted template in the store and reconstructs without any caller-supplied config.

Start-time race

For :self_register (Native) registries the race between whereis returning :none and the new child finishing register/3 is best-effort: a concurrent caller may start a second child, which then loses the race and keeps running unregistered. This was acceptable for single-router usage (Phase 4b).

For via-based registries (Horde) the race is closed: the supervisor supplies a :name computed by child_name/2, so the OTP supervisor performs atomic registration at start. Any concurrent caller that loses the start race gets {:error, {:already_started, pid}}; rehydrate_and_start/1 normalises this to {:ok, pid} so all callers converge on the single winner.

Summary

Functions

approve(opts, decisions)

@spec approve(
  keyword(),
  map()
) :: :ok | {:error, :no_session}

run(opts, user_input)

@spec run(
  keyword(),
  term()
) :: {:ok, term()} | {:error, term()}