Issho.Authority (Issho v0.1.0)

Copy Markdown View Source

The one process that orders a document's changes, across every node of a cluster.

It loads the document from the store (or builds it from the initial content your policy gives), and for each transaction:

  1. checks the envelope (Issho.Transaction) and its receipt: a retry of an accepted transaction gets its revision again, and changes nothing;
  2. applies the operations with the document's engine, all or none;
  3. validates the result (Issho.Engine.validate/2);
  4. saves the document and its content, comparing the stored version;
  5. only then answers the author and broadcasts the transaction.

The stored document is the engine's state with Issho's envelope: the engine's name and version, an epoch, a revision, the state the epoch began with, a journal of the accepted transactions, and their receipts. The journal can rebuild any revision of the epoch (content_at/3), so a form can publish exactly the revision a person saw.

A store that answers {:error, :conflict} means another process saved meanwhile (a node that lost touch with the cluster): this one stops, and the next open loads the newer document.

When no session has used the document for the instance's :ttl (30 seconds), the authority stops; the document stays in the store.

Start an authority with Issho.Documents.open/3, not directly.

Summary

Functions

Which of these transaction ids the author already has accepted, after a reconnect.

Returns a specification to start this module under a supervisor.

Commits a transaction of the actor author (its key). Gives {:ok, %{"id" => id, "revision" => revision}}, with "duplicate" => true for a retry, or {:error, reason}.

The content of the current revision, with its epoch and revision.

The content of an accepted revision of the epoch.

Adds a session (a channel, an agent) that uses the document; the authority stays while one does. Returns the document as a browser receives it, and the document's engine.

The document as a browser receives it: epoch, revision and the engine's snapshot.

Functions

accepted(server, ids, author)

@spec accepted(GenServer.server(), [String.t()], String.t()) :: [String.t()]

Which of these transaction ids the author already has accepted, after a reconnect.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

commit(server, transaction, author)

@spec commit(GenServer.server(), Issho.Transaction.t(), String.t()) ::
  {:ok, map()} | {:error, term()}

Commits a transaction of the actor author (its key). Gives {:ok, %{"id" => id, "revision" => revision}}, with "duplicate" => true for a retry, or {:error, reason}.

content(server)

@spec content(GenServer.server()) :: {:ok, map()} | {:error, term()}

The content of the current revision, with its epoch and revision.

content_at(server, epoch, revision)

@spec content_at(GenServer.server(), String.t(), non_neg_integer()) ::
  {:ok, term()} | {:error, term()}

The content of an accepted revision of the epoch.

join(server, pid)

@spec join(GenServer.server(), pid()) :: {:ok, map(), module()}

Adds a session (a channel, an agent) that uses the document; the authority stays while one does. Returns the document as a browser receives it, and the document's engine.

snapshot(server)

@spec snapshot(GenServer.server()) :: {:ok, map()}

The document as a browser receives it: epoch, revision and the engine's snapshot.