defmodule Runbox.Runtime.Stage.SelectorBuilder do
@moduledoc """
Selector function generator which is used to filter messages between GenStage phases.
Stage based runtime uses BroadcastDispatcher to dispatch messages between TemplateCarriers,
this kind of dispatcher support message selector function to be passed as part of GenStage
subscription. This module is used to generate this function based on template configuration.
"""
alias Runbox.Runtime.OutputAction, as: OA
alias Toolbox.Message, as: M
@doc """
Builds GenStages BroadcastDispatcher filter function based on template configuration.
Filter function is produced based on `c:Runbox.Scenario.Template.StageBased.subscriptions/0`
callback result.
Subscription is defined as {message_type, _routing_rule}, we use only message_type part
of subscription. All message types are stored in produced function clojure and dispatched
message type is matched against them.
Exception to the message type matching are output actions and tick messages which are
always matched.
"""
@spec build([{String.t() | atom, term}]) :: (OA.t() | M.t() -> boolean())
def build(config) do
# parse subscription, take only message type
msg_types = Enum.map(config, fn {msg_type, _} -> msg_type end)
fn
%OA{} ->
# always propagate output actions
true
%M{type: "tick"} ->
# always propagate tick messages
true
%M{type: type} ->
# other message types propagate only if template is subscribed to them
Enum.member?(msg_types, type)
end
end
end