One Leaf.Collab.Room per note, started when somebody opens it.
Leaf holds a shared document in a process and has no opinion about how those processes are named or supervised — that is the host's job, and this is it.
Why a room is temporary
A room that crashes is not restarted with what it was holding, because it is
not holding anything any more: the document lived in its state. The next
person to open the note starts a fresh room, which loads from
PhoenixKitKnowledgeBase.Collab.Store — that is, from the file, which is the
source of truth anyway. Restarting would only produce an empty room wearing
the name of a note.
Stopping rooms
Under Leaf 0.6 a room outlived its sessions: its {:DOWN, …} clause dropped
the departed session and returned {:noreply, …}, with no stop and no idle
timeout, so a room started for a note stayed up for the life of the node.
close_room/1 exists for that — GenServer.stop/1 rather than a kill,
because the last thing a room does is write down what it was holding.
Leaf ≥ 0.8, which is what core admits today, takes :idle_after and stops an
empty room itself. Nothing opens a room yet (this is groundwork; no LiveView
calls room_for/1), so room_spec/1 does not pass it: when rooms are wired
to the editor, pass idle_after: there and close_room/1 becomes the
backstop rather than the only way down.
Why this is in children/0
PhoenixKit.Module collects child specs from every discovered module and
starts them under core's supervisor, so this needs no host setup. They start
whether or not the knowledge base is enabled — a registry and an idle
dynamic supervisor, which cost nothing until a note is opened.
Summary
Functions
Child specs for core's supervisor. See PhoenixKitKnowledgeBase.children/0.
Stop the room for this note, flushing what it holds on the way down.
The room holding this note, started if nobody has opened it yet.
Whether a room is currently open for this note, without starting one.
Functions
@spec children() :: [Supervisor.child_spec() | {module(), term()}]
Child specs for core's supervisor. See PhoenixKitKnowledgeBase.children/0.
@spec close_room(String.t()) :: :ok
Stop the room for this note, flushing what it holds on the way down.
Rooms do not stop themselves — see the moduledoc — so whatever opened one is responsible for this. A note nobody has open should not still have a process.
@spec room_for(PhoenixKitKnowledgeBase.Schemas.Note.t()) :: {:ok, pid()} | {:error, term()}
The room holding this note, started if nobody has opened it yet.
Safe to call from several sessions at once: the loser of the race gets
{:already_started, pid} back from the registry and uses that room, which is
the whole point of naming them.
Whether a room is currently open for this note, without starting one.