Orchestrates the turns of one conversation.
It records each turn in the history before running the handler, runs the handler in a task
under Mead.TurnSupervisor, and replies to the caller once the task reports back. A handler
that raises, exits, returns garbage, or runs past the turn timeout fails only that turn. A
failed turn replies {:error, {:failed, reason}}, with the same reason stored as its output.
The task is linked to the server and the server traps exits. A task failure therefore arrives as a message instead of killing the server, while a server death takes the running task down with it, so no orphaned handler keeps running for a conversation that restarted.
The turn clock can be suspended with pause_clock/1 and resume_clock/1, for a turn that waits
for a person: while at least one pause is open the turn cannot time out, and the last resume
restarts the timer with the time that was left. Pauses nest by counting, and neither call does
anything when no turn is running, so a pause can never leak into the next turn.
When the server restarts after a crash, init/1 marks every turn still recorded as in
progress as interrupted. A reader that bypasses the server can observe the old status in the
moment between the new server registering its name and finishing init/1.
Summary
Functions
Returns a specification to start this module under a supervisor.
Suspends the clock of the running turn; every call must be matched by one resume_clock/1.
:ok when no turn is running, {:error, :not_found} for an unknown session.
Undoes one pause_clock/1; the timer restarts when the last pause is undone.
Starts the server for options[:session_id], registered under Mead.Registry.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec pause_clock(String.t()) :: :ok | {:error, :not_found}
Suspends the clock of the running turn; every call must be matched by one resume_clock/1.
:ok when no turn is running, {:error, :not_found} for an unknown session.
@spec resume_clock(String.t()) :: :ok | {:error, :not_found}
Undoes one pause_clock/1; the timer restarts when the last pause is undone.
@spec start_link(keyword()) :: GenServer.on_start()
Starts the server for options[:session_id], registered under Mead.Registry.
Required options are :session_id, :handler, and :turn_timeout.