Packages
ex_esdb
0.0.17
0.11.0
0.10.0
0.9.0
0.8.0
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14-alpha
0.0.13-alpha
0.0.12-alpha
0.0.11-alpha
0.0.10-alpha
0.0.9-alpha
0.0.8-alpha
0.0.6-alpha
0.0.5-alpha
0.0.4-alpha
0.0.3-alpha
0.0.2-alfa
0.0.1-alfa
ExESDB is a reincarnation of rabbitmq/khepri, specialized for use as a BEAM-native event store.
Current section
Files
Jump to
Current section
Files
lib/repl.ex
defmodule ExESDB.Repl do
@moduledoc """
This module is to interact with the ExESDB.system,
running a store called "reg_gh" (Regulate Greenhouse)
"""
alias ExESDB.Repl.EventGenerator, as: ESGen
alias ExESDB.Repl.Observer, as: Observer
alias ExESDB.Repl.Producer, as: Producer
alias ExESDB.Repl.Subscriber, as: Subscriber
alias ExESDB.GatewayAPI, as: API
require Logger
@store :reg_gh
@greenhouse1 "greenhouse1"
@greenhouse2 "greenhouse2"
@greenhouse3 "greenhouse3"
@greenhouse4 "greenhouse4"
@greenhouse5 "greenhouse5"
@greenhouses [
@greenhouse1,
@greenhouse2,
@greenhouse3,
@greenhouse4,
@greenhouse5
]
def store, do: @store
def stream1, do: @greenhouse1
def stream2, do: @greenhouse2
def stream3, do: @greenhouse3
def stream4, do: @greenhouse4
def stream5, do: @greenhouse5
def get_opts, do: ExESDB.Options.app_env()
def get_streams, do: API.get_streams(@store)
def get_subscriptions, do: API.get_subscriptions(@store)
@doc """
Append events to a stream.
"""
@spec append(
stream :: atom(),
nbr_of_events :: integer()
) :: {:ok, list(), integer()} | {:error, term()}
def append(stream, nbr_of_events) do
{:ok, version} = API.get_version(@store, stream)
events = ESGen.generate_events(version, nbr_of_events)
case @store
|> API.append_events(stream, events) do
{:ok, new_version} ->
{:ok, result} =
@store
|> API.get_events(stream, 1, new_version, :forward)
{:ok, result,
result
|> Enum.count()}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Starts an observer (a transient subscription) for all streams.
"""
@spec start_observer_for_all_streams() :: :ok
def start_observer_for_all_streams do
Logger.warning("Starting Observer for all streams in 5 seconds...
Switch to :observer application to see it come online.")
Process.sleep(5_000)
Observer.start(
store: @store,
type: :by_stream,
selector: "$all"
)
:ok
end
@doc """
Starts an observer (a transient subscription) for a specific stream.
## Parameters
- stream: the stream to subscribe to (default: "$greenhouse-1")
"""
@spec start_observer_for_stream(stream :: String.t()) :: :ok
def start_observer_for_stream(stream \\ "$greenhouse-1") do
Logger.warning("Starting Observer for [#{stream}] in 5 seconds...
Switch to :observer application to see it come online.")
Process.sleep(5_000)
Observer.start(
store: @store,
type: :by_stream,
selector: stream
)
:ok
end
@doc """
Starts an observer for a specific event type.
## Possible event types:
- "initialized:v1" (default)
- "temperature_measured:v1"
- "humidity_measured:v1"
- "light_measured:v1"
- "fan_activated:v1"
- "fan_deactivated:v1"
- "light_activated:v1"
- "light_deactivated:v1"
- "heater_activated:v1"
- "heater_deactivated:v1"
- "sprinkler_activated:v1"
- "sprinkler_deactivated:v1"
- "desired_temperature_set:v1"
- "desired_humidity_set:v1"
- "desired_light_set:v1"
"""
@spec start_observer_for_event_type(event_type :: String.t()) :: :ok
def start_observer_for_event_type(event_type \\ "initialized:v1") do
Logger.warning("Starting Observer for [#{event_type}] in 5 seconds...
Switch to :observer application to see it come online.")
Process.sleep(5_000)
Observer.start(
store: @store,
type: :by_event_type,
selector: event_type
)
:ok
end
@doc """
Starts an observer (a transient subscription) for a specific event payload pattern.
## Parameters
- observer_name: the name of the observer
- event_payload_pattern: the event payload pattern as a map (e.g.: %{operator: "John"})
"""
def start_observer_for_event_payload(
observer_name,
event_payload_pattern
) do
Logger.warning(
"Starting Observer for [#{observer_name}] with [#{inspect(event_payload_pattern, pretty: true)}] in 5 seconds...
Switch to :observer application to see it come online."
)
Process.sleep(5_000)
Observer.start(
store: @store,
type: :by_event_payload,
selector: event_payload_pattern,
name: observer_name
)
:ok
end
@doc """
Starts a subscriber for a specific stream.
## Parameters
- subscription_name: the name of the subscription
- stream: the stream to subscribe to (default: "$greenhouse-1")
- start_from: the version to start from (default: 0)
"""
@spec start_subscriber_for_stream(
subscription_name :: String.t(),
stream :: String.t(),
start_from :: integer()
) :: :ok
def start_subscriber_for_stream(subscription_name, stream \\ "$greenhouse-1", start_from \\ 0) do
Logger.warning(
"Starting Subscriber for [#{subscription_name}] to [#{stream}] from [#{start_from}] in 5 seconds...
Switch to :observer application to see it come online."
)
Process.sleep(5_000)
Subscriber.start(
subscription_name,
stream,
start_from
)
:ok
end
@doc """
Starts a number of producers.
Each producer will append events to a stream with stream id `greenhouse-n`.
Where n is the number of the producer.
"""
def start_producers(nbr_of_producers \\ 10) do
Logger.warning("Starting #{nbr_of_producers} Producers in 5 seconds.
Switch to :observer application to see them come online.")
Process.sleep(5_000)
1..nbr_of_producers
|> Enum.each(fn n -> Producer.start("greenhouse-#{n}") end)
:ok
end
@doc """
Stops a producer for a specific stream_id.
"""
@spec stop_producer_for_stream(stream_id :: String.t()) :: :ok
def stop_producer_for_stream(stream_id \\ "greenhouse-1") do
Producer.stop(stream_id)
end
end