View Source Vectoree.TreeServer (Vectoree v0.0.2)
A module for running a GenServer
process, which acts as a central hosting
point of a "tree" (key-value map). The server can host a local part of a
(typically static) tree, which forms the base for other subtrees, which are
mounted as concurrent processes of type TreeSource
and TreeProcessor
on
the central server. Concurrent processes of type TreeProcessor
and
TreeSink
can be registered on the central server to receive updates on
subtrees via casts.
A TreeServer
can be started in the usual way, i.e. via the
TreeServer.start_link/1
function or as part of a supervision tree. The
server itself spawns a group of DynamicSupervisor
processes for the
supervision of sources, processors and sinks.
There can be only one TreeServer
process being alive on a single ERTS node.
Summary
Functions
Accepts a map and returns a tailored map including only the keys :mount
and
:listen
, depending on what is required.
Returns a specification to start this module under a supervisor.
Mounts the calling process as a source at the given path.
Broadcasts a notification about a changed tree at the given path.
Queries the TreeServer
at the given path and returns the aggregated tree of
path-payload pairs. The aggregated tree is assembled by passing the query on
to all sources and processors, which are mounted on the server.
Queries the TreeServer
at the given path and applies a custom function on
each replied chunk and by using given accumulator (if required).
Registers the calling process as a sink (listener) at the given path.
Starts a new server process linked to the current process. See
GenServer.start_link
for detailed documentation.
Starts a processor via the given TreeServer
denoted by the given module.
Paths must be given at which the processor' internal tree is mounted on the
base tree and at which the processor shall listen for updates.
Starts a sink via the given TreeServer
denoted by the given module. A path
must be given at which the sink shall listen for updates.
Starts a source via the given TreeServer
denoted by the given module. A path
must be given at which the sources' internal tree is mounted on the base tree.
Stops a processor via the given TreeServer
denoted by its PID.
Stops a sink via the given TreeServer
denoted by its PID.
Stops a source via the given TreeServer
denoted by its PID.
Types
@type path() :: %Vectoree.TreePath{segments: term()}
Functions
@spec args2info(%{mount: path(), listen: path()}) :: %{mount: path(), listen: path()}
@spec args2info(%{mount: path()}) :: %{mount: path()}
@spec args2info(%{listen: path()}) :: %{listen: path()}
@spec args2info((... -> any())) :: %{mount: path(), listen: path()}
Accepts a map and returns a tailored map including only the keys :mount
and
:listen
, depending on what is required.
Examples
iex> Vectoree.TreeServer.args2info(%{mount: ~p"a.b.c", foo: :bar, listen: ~p"a.b"})
%{mount: ~p"a.b.c", listen: ~p"a.b"}
iex> Vectoree.TreeServer.args2info(%{mount: ~p"a.b.c", foo: :bar})
%{mount: ~p"a.b.c"}
iex> Vectoree.TreeServer.args2info(%{foo: :bar, listen: ~p"a.b"})
%{listen: ~p"a.b"}
iex> Vectoree.TreeServer.args2info(fn -> %{foo: :bar, listen: ~p"a.b"} end)
%{listen: ~p"a.b"}
Returns a specification to start this module under a supervisor.
See Supervisor
.
Mounts the calling process as a source at the given path.
Broadcasts a notification about a changed tree at the given path.
notify/2
computes an enumeration of all registered listeners for which the
notification is relevant and then uses notify/3
to broadcast the
notification to each particular process.
@spec notify(GenServer.server(), path(), map()) :: :ok
@spec query(GenServer.server(), path(), [{:chunk_size, integer()}]) :: map()
Queries the TreeServer
at the given path and returns the aggregated tree of
path-payload pairs. The aggregated tree is assembled by passing the query on
to all sources and processors, which are mounted on the server.
The opts
keyword list may contain a :chunk_size
item with an integer,
which is used for chunking the replies coming from all sources and processors.
This can be useful in case of large trees (millions of entries).
Examples
Vectoree.TreeServer.query(server_pid, ~p"a.b")
#=> %{...}
Vectoree.TreeServer.query(server_pid, ~p"a", chunk_size: 1000)
#=> %{...}
@spec query_apply(GenServer.server(), path(), any(), (... -> any()), [ {:chunk_size, integer()} ]) :: any()
Queries the TreeServer
at the given path and applies a custom function on
each replied chunk and by using given accumulator (if required).
The function arguments are
- the control atom of the chunk, one of
:cont
indicating more replies to come:ok
indicating the last chunk
- the chunk (a map)
- the accumulator
Examples
fun = fn _ctrl, chunk, acc -> Map.merge(acc, chunk) end
Vectoree.TreeServer.query_apply(server_pid, ~p"a", %{}, fun, chunk_size: 1000)
#=> %{...}
Registers the calling process as a sink (listener) at the given path.
@spec start_link([{:tree, map()}]) :: GenServer.on_start()
Starts a new server process linked to the current process. See
GenServer.start_link
for detailed documentation.
The opts
keyword list may contain a :tree
item with a value of type map,
which is used as the base tree for the server.
Examples
Vectoree.TreeServer.start_link(tree: %{~p"a.b" => :payload})
{:ok, pid}
@spec start_processor(GenServer.server(), module(), path(), path()) :: GenServer.on_start()
Starts a processor via the given TreeServer
denoted by the given module.
Paths must be given at which the processor' internal tree is mounted on the
base tree and at which the processor shall listen for updates.
Examples
Vectoree.TreeServer.start_processor(server_pid, CustomSource, ~p"a.b.p0", ~p"a.b.c.d")
{:ok, pid}
@spec start_sink(GenServer.server(), module(), path()) :: GenServer.on_start()
Starts a sink via the given TreeServer
denoted by the given module. A path
must be given at which the sink shall listen for updates.
Examples
Vectoree.TreeServer.start_sink(server_pid, CustomSource, ~p"a.b.p0", ~p"a.b.c.d")
{:ok, pid}
@spec start_source(GenServer.server(), module(), path()) :: GenServer.on_start()
Starts a source via the given TreeServer
denoted by the given module. A path
must be given at which the sources' internal tree is mounted on the base tree.
Examples
Vectoree.TreeServer.start_source(server_pid, CustomSource, ~p"a.b.s0")
{:ok, pid}
@spec stop_processor(GenServer.server(), pid()) :: :ok | {:error, :not_found}
Stops a processor via the given TreeServer
denoted by its PID.
Examples
Vectoree.TreeServer.stop_processor(server_pid, source_pid)
:ok
@spec stop_sink(GenServer.server(), pid()) :: :ok | {:error, :not_found}
Stops a sink via the given TreeServer
denoted by its PID.
Examples
Vectoree.TreeServer.stop_processor(server_pid, source_pid)
:ok
@spec stop_source(GenServer.server(), pid()) :: :ok | {:error, :not_found}
Stops a source via the given TreeServer
denoted by its PID.
Examples
Vectoree.TreeServer.stop_source(server_pid, source_pid)
:ok