Issho.Awareness (Issho v0.1.0)

Copy Markdown View Source

Where the people of a room are, and what they are doing: their places, selections, drags and locks, many times a second.

Awareness is ephemeral by design: never saved, never replicated by Phoenix.Presence's CRDT, and only the latest state of each session matters. A room has one awareness process on each node where it has sessions. Each one:

  • keeps the latest state of each local session (put/5);
  • every :awareness_interval (50 ms), sends one frame with the states that changed, to the room's sessions on every node, so that each session receives about 20 frames a second whatever the size of the room, instead of a message from every other person on every move;
  • sends every state now and then (:awareness_full_every frames, 5 seconds), and when another node's awareness of the room starts, so that a session that missed a frame, or joined late, catches up;
  • forgets a session when its process stops, and a node it stopped hearing from;
  • keeps the room's whole picture from every node's frames, for states/2 and locks/2 (agents that look before they act).

It stops when its node has no session left in the room.

A state is a map of the binding's choosing; Issho reads "place" (an Issho.Place), "locks" (a list of places) and "status".

Summary

Functions

The places locked in the room, each with the key of the actor that holds it.

Sets the state of a session (a channel or an agent process, pid) in the room, for the actor key. nil clears it.

The session id of a process, as frames name it.

The states of the room, from every node: %{session_id => %{"key" => actor_key, "state" => state}}.

Functions

locks(instance, room)

@spec locks(atom(), String.t()) :: [{term(), String.t()}]

The places locked in the room, each with the key of the actor that holds it.

put(instance, room, key, state, pid \\ self())

@spec put(atom(), String.t(), String.t(), map() | nil, pid()) :: :ok

Sets the state of a session (a channel or an agent process, pid) in the room, for the actor key. nil clears it.

session_id(pid)

@spec session_id(pid()) :: String.t()

The session id of a process, as frames name it.

states(instance, room)

@spec states(atom(), String.t()) :: map()

The states of the room, from every node: %{session_id => %{"key" => actor_key, "state" => state}}.