The feed behaviour: what fills a chart's source slot, asked for rows (spec/08 §11, D-140).
A feed is a struct whose module implements this behaviour. describe/1 answers the
feed's schema, its version and supports, the capabilities it honours among
[:window, :budget, :push]; fetch/3 answers a Visualize.Data.Delivery for a window
and a budget; subscribe/2 and unsubscribe/2 are for a feed that pushes. Only rows
are required. A window and a budget are requests: where a feed does not honour one,
finish/3 trims and reduces for it and the delivery records reduced_by: :visualize.
Every callback answers {:error, reason} rather than raising, so a feed that is down is
a value a cell shows.
A push feed sends {:visualize_feed, ref, {:schema, version, schema}} before the first
delivery naming version, then {:visualize_feed, ref, {:delivery, delivery}}, each a
delivery of the rows new since the last (spec/08 §11.3). Visualize.Feed.Monitor runs
the loop over many feeds; Visualize.Feed.Combine makes one feed of several by window.
Examples
iex> alias Visualize.Data.{Delivery, Schema}
iex> schema = Schema.new!(%{t: %{type: :number, window: true}, v: %{type: :number}, s: %{type: :category}})
iex> rows = for t <- 1..10, s <- ["a", "b"], do: %{t: t, v: rem(t * 7, 5), s: s}
iex> delivery = Visualize.Feed.finish(Delivery.new(rows), schema, supports: [], budget: 8)
iex> {length(delivery.rows), delivery.reduced_by}
{8, :visualize}
Summary
Types
nil, or the most rows a cell wants.
What a feed honours (spec/08 §11.1).
A feed: a struct whose module implements Visualize.Feed.
nil, or [from, to] over the feed's window field, either bound nil for open.
Callbacks
The feed's present schema, its version and the capabilities it honours.
The rows for a window and a budget, both requests.
The feed's pushes sent to pid, tagged with the answered reference.
A subscription stopped.
Functions
The three capabilities a feed may honour, in the order of spec/08 §11.1.
The feed's {version, schema, supports}, or {:error, reason}.
A map of feeds by name as the describe function of spec/08 §10.3, for
Visualize.Data.Schema.Cache.resolve/4 and Visualize.Chart.apply/2's describe:.
A name not in the map is {:error, :no_feed}.
fetch(feed, window, budget): {:ok, delivery} or {:error, reason}.
A delivery finished for a request (spec/08 §11.2): trimmed to window: when
supports: lacks :window and the schema has a window field, and reduced to budget:
by reduce: (:lttb or :m4) when supports: lacks :budget and there are more
rows than the budget, recording reduced_by: :visualize. A delivery that needs
neither comes back as it is.
The feed's pushes sent to pid (spec/08 §11.3): {:ok, ref}, or {:error, :no_push}
for a feed whose module does not implement subscribe/2.
A subscription stopped; :ok for a feed that does not push.
The schema's window field (spec/08 §10.1, §11.2, D-154): the field a window is over, by
which rows are ordered, trimmed and routed. It is the field described window: true,
else the schema's one :time field when it does not say window: false; nil when
there is neither.
The type of the schema's window field, :time or :number, or nil when it has none:
the kind of window that applies to it (Visualize.Feed.Window.applies?/2).
Types
@type budget() :: pos_integer() | nil
nil, or the most rows a cell wants.
@type capability() :: :window | :budget | :push
What a feed honours (spec/08 §11.1).
@type t() :: struct()
A feed: a struct whose module implements Visualize.Feed.
@type window() :: Visualize.Feed.Window.t()
nil, or [from, to] over the feed's window field, either bound nil for open.
Callbacks
@callback describe(feed :: t()) :: {String.t(), Visualize.Data.Schema.t(), [capability()]} | {:error, term()}
The feed's present schema, its version and the capabilities it honours.
@callback fetch(feed :: t(), window(), budget()) :: {:ok, Visualize.Data.Delivery.t()} | {:error, term()}
The rows for a window and a budget, both requests.
The feed's pushes sent to pid, tagged with the answered reference.
A subscription stopped.
Functions
@spec capabilities() :: [capability(), ...]
The three capabilities a feed may honour, in the order of spec/08 §11.1.
@spec describe(t()) :: {String.t(), Visualize.Data.Schema.t(), [capability()]} | {:error, term()}
The feed's {version, schema, supports}, or {:error, reason}.
@spec describer(%{required(term()) => t()}) :: (term() -> {:ok, Visualize.Data.Schema.t()} | {:error, term()})
A map of feeds by name as the describe function of spec/08 §10.3, for
Visualize.Data.Schema.Cache.resolve/4 and Visualize.Chart.apply/2's describe:.
A name not in the map is {:error, :no_feed}.
@spec fetch(t(), window(), budget()) :: {:ok, Visualize.Data.Delivery.t()} | {:error, term()}
fetch(feed, window, budget): {:ok, delivery} or {:error, reason}.
@spec finish(Visualize.Data.Delivery.t(), Visualize.Data.Schema.t(), keyword()) :: Visualize.Data.Delivery.t()
A delivery finished for a request (spec/08 §11.2): trimmed to window: when
supports: lacks :window and the schema has a window field, and reduced to budget:
by reduce: (:lttb or :m4) when supports: lacks :budget and there are more
rows than the budget, recording reduced_by: :visualize. A delivery that needs
neither comes back as it is.
The feed's pushes sent to pid (spec/08 §11.3): {:ok, ref}, or {:error, :no_push}
for a feed whose module does not implement subscribe/2.
A subscription stopped; :ok for a feed that does not push.
@spec window_field(Visualize.Data.Schema.t()) :: Visualize.Data.Schema.name() | nil
The schema's window field (spec/08 §10.1, §11.2, D-154): the field a window is over, by
which rows are ordered, trimmed and routed. It is the field described window: true,
else the schema's one :time field when it does not say window: false; nil when
there is neither.
iex> alias Visualize.Data.Schema
iex> Visualize.Feed.window_field(Schema.new!(%{t: %{type: :time}, v: %{type: :number}}))
:t
iex> Visualize.Feed.window_field(Schema.new!(%{tick: %{type: :number, window: true}, v: %{type: :number}}))
:tick
iex> Visualize.Feed.window_field(Schema.new!(%{a: %{type: :time}, b: %{type: :time}}))
nil
@spec window_type(Visualize.Data.Schema.t()) :: :time | :number | nil
The type of the schema's window field, :time or :number, or nil when it has none:
the kind of window that applies to it (Visualize.Feed.Window.applies?/2).