Slap.Yjs.Docs (slap_yjs v0.4.0)

Copy Markdown View Source

The document servers of this node, one per {module, doc_id}, started on the first join/3 and stopped after :idle_timeout without subscribers. Each node that has clients for a document runs its own server; the servers share the document through its .updates stream and presence through a :pg group (see Slap.Yjs.DocServer).

Invalid control options and unknown option names raise ArgumentError.

Start it after the Streams cluster, so document servers can store their buffers during shutdown. :name and :prefix select a document-server instance on the built-in Streams cluster:

children = [Slap.Streams.Cluster, Slap.Yjs.Docs]
children = [Slap.Streams.Cluster,
            {Slap.Yjs.Docs, name: MyDocs, prefix: "/my/streams"}]
Slap.Yjs.Docs.join(MyDocServer, {"service", "document"}, docs: MyDocs)

For an application-owned Streams cluster defined with use Slap.Streams.Cluster, pass cluster: MyApp.StreamsCluster when starting Docs. Run one Streams cluster per VM.

Summary

Functions

Returns a specification to start this module under a supervisor.

Deletes the document for good (Slap.Yjs.Store.delete_doc/1), then stops its servers on every node with {:shutdown, :deleted}, waiting up to :timeout ms (default 5 s) for them. :docs selects a named instance. Joins return {:error, :deleted} from then on, so a deleted document's id cannot be reused. A server that does not stop in time (on a node that cannot be reached) stops once its follower finds the document deleted, and cannot store anything meanwhile.

Subscribes the caller to the document's server on this node, starting it with opts (Slap.Yjs.DocServer options; :idle_timeout defaults to 30 s) if it is not running. Server options, and :assigns (a map of the server's initial assigns), apply only when the server starts. The caller then gets the messages described in Slap.Yjs.DocServer, and should monitor the returned pid: if the server stops, join again and resynchronise. {:error, :deleted} if the document was deleted (delete/2). :docs selects a named Docs instance; :timeout bounds loading and subscribing (default 5 s).

Unsubscribes the caller. :timeout defaults to 5,000 ms.

Starts a document server supervisor. :name selects the instance name; :cluster selects its Streams cluster (see Slap.Streams.Cluster); :prefix prefixes stored paths.

The document's server on this node, if it has finished loading.

Functions

child_spec(init_arg)

@spec child_spec(keyword()) :: Supervisor.child_spec()

Returns a specification to start this module under a supervisor.

See Supervisor.

delete(doc_id, opts \\ [])

@spec delete(Slap.Yjs.Store.doc(), keyword()) :: :ok | {:error, term()}

Deletes the document for good (Slap.Yjs.Store.delete_doc/1), then stops its servers on every node with {:shutdown, :deleted}, waiting up to :timeout ms (default 5 s) for them. :docs selects a named instance. Joins return {:error, :deleted} from then on, so a deleted document's id cannot be reused. A server that does not stop in time (on a node that cannot be reached) stops once its follower finds the document deleted, and cannot store anything meanwhile.

join(module, doc_id, opts \\ [])

@spec join(module(), Slap.Yjs.Store.doc(), keyword()) ::
  {:ok, pid()} | {:error, term()}

Subscribes the caller to the document's server on this node, starting it with opts (Slap.Yjs.DocServer options; :idle_timeout defaults to 30 s) if it is not running. Server options, and :assigns (a map of the server's initial assigns), apply only when the server starts. The caller then gets the messages described in Slap.Yjs.DocServer, and should monitor the returned pid: if the server stops, join again and resynchronise. {:error, :deleted} if the document was deleted (delete/2). :docs selects a named Docs instance; :timeout bounds loading and subscribing (default 5 s).

leave(pid, opts \\ [])

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

Unsubscribes the caller. :timeout defaults to 5,000 ms.

start_link(opts \\ [])

Starts a document server supervisor. :name selects the instance name; :cluster selects its Streams cluster (see Slap.Streams.Cluster); :prefix prefixes stored paths.

whereis(module, doc_id, opts \\ [])

@spec whereis(module(), Slap.Yjs.Store.doc(), keyword()) :: pid() | nil

The document's server on this node, if it has finished loading.