Macaw.Data.Source behaviour (macaw_data v0.5.3)

Copy Markdown View Source

The source contract (spec/01 §2): anything a component's slot reads. One contract serves feeds, queries, derived sources, state sources and exports. It is a strict superset of visualize's Visualize.Feed: an existing feed is a source with no parameters.

A source is a struct whose module implements this behavior:

  • describe(source, context): what the source is, a Macaw.Data.Source.Description. It takes the host's configuration for the source as context, never a viewer, so it is answered at boot and cached by schema version;
  • fetch(source, request): one answer, a Macaw.Data.Delivery, for a Macaw.Data.Source.Request;
  • subscribe(source, pid) and unsubscribe(source, ref), optional, for a source that pushes (spec/01 §4).

Errors are values: every callback answers {:error, reason} rather than raising.

The functions here dispatch to a source's module. fetch/3 checks the request's parameters against the description's before the call (Macaw.Data.Parameter.validate/2): a request with a bad parameter never reaches the source, and the source receives every parameter, defaults filled in.

Summary

Types

t()

A source: a struct whose module implements Macaw.Data.Source.

Callbacks

What the source is, from the host's configuration for it; never a viewer.

One answer for a request.

The source's pushes sent to pid, tagged with the answered reference (spec/01 §4).

A subscription stopped.

Functions

The source's description, {:ok, description} or {:error, reason}. An answer that is neither is {:error, {:bad_describe, answer}}: a source's fault the caller can show.

A map of sources by name, with the host's context for each, as the describe function Macaw.Data.Schema.Cache.resolve/4 takes: a name's present schema, or {:error, :no_source} for a name not in the map.

One answer for a request, checked first against the description: {:error, {:params, faults}} without calling the source when a parameter is unknown, missing or not legal (Macaw.Data.Parameter.validate/2). Otherwise the source is called with every parameter, defaults filled in. An answer that is neither {:ok, delivery} nor {:error, reason} is {:error, {:bad_fetch, answer}}.

The source's pushes sent to pid (spec/01 §4): {:ok, ref}, or {:error, :no_push} for a source whose module does not implement subscribe/2.

A subscription stopped; :ok for a source that does not push.

Types

t()

@type t() :: struct()

A source: a struct whose module implements Macaw.Data.Source.

Callbacks

describe(source, context)

@callback describe(source :: t(), context :: term()) ::
  {:ok, Macaw.Data.Source.Description.t()} | {:error, term()}

What the source is, from the host's configuration for it; never a viewer.

fetch(source, t)

@callback fetch(source :: t(), Macaw.Data.Source.Request.t()) ::
  {:ok, Macaw.Data.Delivery.t()} | {:error, term()}

One answer for a request.

subscribe(source, pid)

(optional)
@callback subscribe(source :: t(), pid()) :: {:ok, reference()} | {:error, term()}

The source's pushes sent to pid, tagged with the answered reference (spec/01 §4).

unsubscribe(source, reference)

(optional)
@callback unsubscribe(source :: t(), reference()) :: :ok

A subscription stopped.

Functions

describe(source, context)

@spec describe(t(), term()) ::
  {:ok, Macaw.Data.Source.Description.t()} | {:error, term()}

The source's description, {:ok, description} or {:error, reason}. An answer that is neither is {:error, {:bad_describe, answer}}: a source's fault the caller can show.

describer(sources)

@spec describer(%{required(term()) => {t(), term()}}) :: (term() ->
                                                      {:ok,
                                                       Macaw.Data.Schema.t()}
                                                      | {:error, term()})

A map of sources by name, with the host's context for each, as the describe function Macaw.Data.Schema.Cache.resolve/4 takes: a name's present schema, or {:error, :no_source} for a name not in the map.

fetch(source, description, request)

One answer for a request, checked first against the description: {:error, {:params, faults}} without calling the source when a parameter is unknown, missing or not legal (Macaw.Data.Parameter.validate/2). Otherwise the source is called with every parameter, defaults filled in. An answer that is neither {:ok, delivery} nor {:error, reason} is {:error, {:bad_fetch, answer}}.

subscribe(source, pid)

@spec subscribe(t(), pid()) :: {:ok, reference()} | {:error, term()}

The source's pushes sent to pid (spec/01 §4): {:ok, ref}, or {:error, :no_push} for a source whose module does not implement subscribe/2.

unsubscribe(source, ref)

@spec unsubscribe(t(), reference()) :: :ok

A subscription stopped; :ok for a source that does not push.