### Start Event Bus Application in Mixfile Source: https://github.com/otobus/event_bus/wiki/Installing-Library-Package To ensure the event_bus application runs, add `:event_bus` to the `applications` list within the `application/0` function in your `mix.exs` file. This integrates the event bus into your project's supervision tree. ```elixir def application do [ applications: [ # ..., :event_bus ] ] end ``` -------------------------------- ### Add Event Bus Dependency to Mixfile Source: https://github.com/otobus/event_bus/wiki/Installing-Library-Package Install the event_bus library by adding it to the dependencies list in your `mix.exs` file. This ensures the package is recognized by Mix. ```elixir def deps do [ # ..., {:event_bus, "~> 1.6.0"} ] end ``` -------------------------------- ### Fetch Event Bus Package with Mix Source: https://github.com/otobus/event_bus/wiki/Installing-Library-Package After adding the dependency, run `mix deps.get` in your project's root directory to download and install the event_bus package from Hex. This command resolves and fetches all project dependencies. ```shell mix deps.get ``` -------------------------------- ### EventBus.notify Event Example Source: https://github.com/otobus/event_bus/wiki/Workflow Illustrates the initial event notification to the EventBus. This function call needs to be implemented by the user's application. ```elixir EventBus.notify(%EventBus.Model.Event{}) ``` -------------------------------- ### Install event_bus_metrics Package Source: https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI This snippet shows how to add the event_bus_metrics package as a dependency in your Elixir project's mix.exs file. Ensure you also add it to the extra_applications list. ```elixir def deps do [ {:event_bus_metrics, "~> 0.3"} ] end def application do [ extra_applications: [..., :event_bus, :event_bus_metrics, ...], ... ] end ``` -------------------------------- ### Subscribe Consumer to Topics Matching Pattern - Elixir Source: https://github.com/otobus/event_bus/wiki/Subscribing-Consumers-to-Topic(s) Subscribes a consumer to topics that start with a specific pattern, for example, all topics starting with ':user_'. It utilizes a regex '^user_*' to match these topics. The subscriber and the list of topic patterns are passed to EventBus.subscribe. ```elixir subscriber = MyFirstConsumer topics = ["^user_*"] EventBus.subscribe({subscriber, topics}) ``` -------------------------------- ### Configure Event Topics in config.exs Source: https://github.com/otobus/event_bus/blob/main/README.md Registers initial event topics for the EventBus. This configuration is loaded when your Elixir application starts. ```elixir config :event_bus, topics: [:message_received, :another_event_occurred] ``` -------------------------------- ### Define an Event Struct Source: https://github.com/otobus/event_bus/blob/main/README.md Demonstrates how to create an instance of the `EventBus.Model.Event` struct. It shows the required fields and provides examples of event data. Emphasizes the need for unique identifiers per event. ```elixir alias EventBus.Model.Event event = %Event{id: "123", transaction_id: "1", topic: :hello_received, data: %{message: "Hello"}} another_event = %Event{id: "124", transaction_id: "1", topic: :bye_received, data: [user_id: 1, goal: "exit"]} ``` -------------------------------- ### Subscriber Mark as Completed Example Source: https://github.com/otobus/event_bus/wiki/Workflow Illustrates a subscriber marking an event as completed. This function call needs to be implemented by the subscriber's application. ```elixir EventBus.mark_as_completed({topic, event_id}) ``` -------------------------------- ### Subscriber Fetch Event Example Source: https://github.com/otobus/event_bus/wiki/Workflow Represents a subscriber fetching an event from the EventBus. This function call needs to be implemented by the subscriber's application. ```elixir EventBus.fetch_event({topic, event_id}) ``` -------------------------------- ### Install EventBus Dependency in Mix Project Source: https://github.com/otobus/event_bus/blob/main/README.md Adds the event_bus library to your project's dependencies. Ensure to include it in your application's supervision tree by adding :event_bus to the applications list in mix.exs. ```elixir def deps do [ {:event_bus, "~> 1.7.0"} ] end def application do [ applications: [ # ... :event_bus ] ] end ``` -------------------------------- ### Subscribe with Subscriber Configuration Source: https://github.com/otobus/event_bus/blob/main/README.md Provides a way to subscribe to events when the subscriber requires a configuration. The configuration is passed as a map along with the subscriber module. This allows for more complex subscriber setups. ```elixir config = %{} subscriber = {MyEventSubscriber, config} EventBus.subscribe({subscriber, ["*"]}) ``` -------------------------------- ### Elixir Querying Unprocessed Events from ETS Watcher Table Source: https://github.com/otobus/event_bus/blob/main/README.md Shows how to query the ETS watcher table to retrieve unprocessed events. This example demonstrates fetching the list of tuples containing event IDs, subscriber lists, completers, and skippers for a specific event topic. ```elixir # The following command will return a list of tuples with the `id`, and `event_subscribers_list` where `subscribers` is the list of event subscribers, `completers` is the subscribers those processed the event and notified `Observation Manager`, and lastly `skippers` is the subscribers those skipped the event without processing. # Assume you have an event with the name ':hello_received' :ets.tab2list(:eb_ew_hello_received) > [{id, {subscribers, completers, skippers}}, ...] ``` -------------------------------- ### Route Metrics to EventBus.Metrics.Web.Router Source: https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI Forward an unused path in your application's router.ex to EventBus.Metrics.Web.Router to enable access to the metrics endpoints. This setup allows the metrics UI and API to be served under a specific base path. ```elixir forward "/event_bus", to: EventBus.Metrics.Web.Router ``` -------------------------------- ### Persistent Event Storage Pattern Source: https://context7.com/otobus/event_bus/llms.txt Implement a dedicated GenServer module to persist all events to a database or external system. This pattern involves subscribing to all events and inserting them into permanent storage. The example shows a basic implementation using PostgreSQL. ```elixir defmodule PersistentEventStore do use GenServer def start_link(_) do GenServer.start_link(__MODULE__, nil, name: __MODULE__) end def init(_) do # Subscribe to all events with wildcard pattern EventBus.subscribe({__MODULE__, [".*"]}) {:ok, %{connection: establish_db_connection()}} end def process({topic, id}) do GenServer.cast(__MODULE__, {topic, id}) :ok end def handle_cast({topic, id}, %{connection: conn} = state) do event = EventBus.fetch_event({topic, id}) # Persist to permanent storage :ok = insert_event_to_postgres(conn, %{ event_id: event.id, topic: event.topic, transaction_id: event.transaction_id, data: Jason.encode!(event.data), occurred_at: event.occurred_at, source: event.source }) # Always mark as completed EventBus.mark_as_completed({__MODULE__, {topic, id}}) {:noreply, state} end defp establish_db_connection do # Return database connection :connection end defp insert_event_to_postgres(conn, event_attrs) do # SQL INSERT implementation :ok end end # Add to application supervision tree children = [ # ... other children PersistentEventStore ] Supervisor.start_link(children, strategy: :one_for_one) ``` -------------------------------- ### Simple Event Consumer with EventBus Source: https://github.com/otobus/event_bus/wiki/Creating-Event-Consumers Demonstrates a basic event consumer implementation for the event_bus library. This module implements the `process/1` function to handle events. It fetches the event data using `EventBus.fetch` and marks it as completed using `EventBus.mark_as_completed`. Dependencies include the `event_bus` library and `Logger`. Inputs are event shadows (topic, id), and outputs are logged information and marked completion. ```elixir defmodule MyFirstConsumer do @moduledoc false require Logger def process({_topic, _id} = event_shadow) do # Fetch event event = EventBus.fetch(event_shadow) # Do something with the event Logger.info("I am handling the event with a Simple module #{__MODULE__}") Logger.info(fn -> inspect(event) end) # Mark the event as completed for this consumer EventBus.mark_as_completed({MyFirstConsumer, event_shadow}) end end ``` -------------------------------- ### Asynchronous Event Consumer with Spawn (event_bus) Source: https://github.com/otobus/event_bus/wiki/Creating-Event-Consumers Illustrates an asynchronous event consumer using Elixir's `spawn` function with the event_bus library. This approach prevents blocking the event processing flow. The `process/1` function spawns a new process to handle event fetching and logging. Dependencies include `event_bus` and `Logger`. The `do_something/1` function fetches and logs event data, then marks completion. ```elixir defmodule MySecondConsumer do @moduledoc false require Logger def process({_topic, _id} = event_shadow) do spawn(fn -> do_something(event_shadow) end) end def do_something(event_shadow) do # Fetch event event = EventBus.fetch(event_shadow) # Do something with the event # Or just log for the sample Logger.info("I am handling the event with Spawn") Logger.info(fn -> inspect(event) end) # Mark the event as completed for `MySecondConsumer` EventBus.mark_as_completed({MySecondConsumer, event_shadow}) end end ``` -------------------------------- ### Register Event Bus Topics in Configuration Source: https://github.com/otobus/event_bus/wiki/Creating-(Registering)-Topics Registering event topics within the `config.exs` file ensures they are available across all environments. This is the recommended approach for topics used consistently throughout the application. Topics are defined as a list of atoms. ```elixir config :event_bus, topics: [ :checkout_completed, :email_sent, :payment_failed, :user_created, :user_activated, # more topics... ] ``` -------------------------------- ### Asynchronous Event Consumer with GenServer (event_bus) Source: https://github.com/otobus/event_bus/wiki/Creating-Event-Consumers Presents an asynchronous event consumer implementation using Elixir's `GenServer` with the event_bus library. This pattern is common for concurrent processing. The consumer uses `GenServer.cast` to handle events asynchronously. It fetches event data via `EventBus.fetch_event` and marks it as completed. Dependencies include `GenServer`, `event_bus`, and `Logger`. ```elixir defmodule MyThirdConsumer do @moduledoc false use GenServer require Logger @doc false def start_link do GenServer.start_link(__MODULE__, [], name: __MODULE__) end @doc false def init(_opts) do {:ok, []} end def process({_topic, _id} = event_shadow) do GenServer.cast(__MODULE__, event_shadow) end def handle_cast({topic, id}, state) do # Fetch event event = EventBus.fetch_event({topic, id}) # Do something with the event # Or just log for the sample Logger.info("I am handling the event with GenServer #{__MODULE__}") Logger.info(fn -> inspect(event) end) # Mark the event as completed for this consumer EventBus.mark_as_completed({__MODULE__, topic, id}) {:noreply, state} end end ``` -------------------------------- ### Asynchronous Event Consumer with GenStage (event_bus) Source: https://github.com/otobus/event_bus/wiki/Creating-Event-Consumers Details an asynchronous event consumer using `GenStage` in conjunction with the event_bus library, designed for handling backpressure and large event queues. It includes a `Queue` module (producer) and a `Worker` module (consumer). Events are pushed to the `Queue` and then processed by the `Worker`, which fetches and logs event data. Dependencies include `GenStage`, `event_bus`, and `Logger`. ```elixir defmodule MyFourthConsumer do @moduledoc false alias MyFourthConsumer.Queue @doc """ Enqueue EventBus events to a GenStage consumer """ def process({_topic, _id} = event_shadow) do Queue.push(event_shadow) end defmodule Queue do use GenStage def init(state) do {:producer, state, buffer_size: :infinity} end def start_link(state \\\[]) do GenStage.start_link(__MODULE__, state, name: __MODULE__) end @doc """ Push event shadows to queue """ def push({_topic, _id} = event_shadow) do GenServer.cast(__MODULE__, {:push, event_shadow}) end @doc false def handle_cast({:push, event_shadow}, state) do {:noreply, [event_shadow], state} end @doc false def handle_demand(_demand, state) do {:noreply, [], state} end end defmodule Worker do @moduledoc false use GenStage require Logger def init(:ok) do { :consumer, :ok, subscribe_to: [ { MyFourthConsumer.Queue, min_demand: 0, max_demand: 1 } ] } end def start_link do GenStage.start_link(__MODULE__, :ok) end @doc false def handle_events([{topic, id}], _from, state) do # Fetch event event = EventBus.fetch_event({topic, id}) # Do something with the event # Or just log for the sample Logger.info("I am handling the event with GenStage #{__MODULE__}") Logger.info(fn -> inspect(event) end) EventBus.mark_as_completed({MyFourthConsumer, topic, id}) {:noreply, [], state} end end end ``` -------------------------------- ### Registering EventBus Topics with Extended Tracing in Elixir Source: https://github.com/otobus/event_bus/wiki/Tracing-System-Events Demonstrates how to extend EventBus functionality in Elixir to trace topic registrations. This involves creating a wrapper module that intercepts topic registration calls, logs the action, and then proceeds with the original EventBus registration. Assumes the use of a UUID library for generating unique IDs. ```elixir defmodule EventBus.Extended do use EventBus.EventSource @sys_topic :eb_sys_event_occurred @source "EventBus.Extended" def register_topic(topic) do EventSource.notify sys_params() do EventBus.register(topic) %{action: :register_topic, topic: topic} end :ok end defp sys_params do id = UUID.uuid4() # Assumed you are using UUID for id generation %{id: id, transaction_id: id, topic: @sys_topic, source: @source} end end ``` -------------------------------- ### Track Event Processing Status Source: https://context7.com/otobus/event_bus/llms.txt Monitor event processing status and manually mark completion or skip. Events are automatically tracked after subscription. This example shows how to subscribe, notify, and mark an event as completed or skipped within a subscriber module. ```elixir # After subscribing, events are automatically tracked EventBus.subscribe({AnalyticsSubscriber, [".*"]}) # Notify an event event = %Event{id: "evt_500", topic: :order_placed, data: %{order_id: 42}} EventBus.notify(event) # In your subscriber, mark processing status defmodule AnalyticsSubscriber do def process({topic, id} = event_shadow) do event = EventBus.fetch_event(event_shadow) case track_analytics(event.data) do :ok -> # Mark as successfully completed EventBus.mark_as_completed({__MODULE__, event_shadow}) {:error, _reason} -> # Mark as skipped (subscriber couldn't process) EventBus.mark_as_skipped({__MODULE__, event_shadow}) end :ok end defp track_analytics(_data), do: :ok end # Alternative syntax with separate topic and id EventBus.mark_as_completed({AnalyticsSubscriber, :order_placed, "evt_500"}) # => :ok # For configured subscribers config = %{endpoint: "https://api.example.com"} subscriber = {AnalyticsSubscriber, config} EventBus.mark_as_completed({subscriber, :order_placed, "evt_500"}) # => :ok # Query ETS watcher table directly for debugging (unprocessed events) :ets.tab2list(:eb_ew_order_placed) # => [{"evt_500", {[AnalyticsSubscriber], [], []}}] # Format: {id, {subscribers, completers, skippers}} ``` -------------------------------- ### Implement Event Subscribers with GenServer in Elixir Source: https://context7.com/otobus/event_bus/llms.txt Event subscribers are implemented as GenServer processes that subscribe to specific event topics using EventBus.subscribe/1. The `process/1` callback receives an event shadow (topic + id tuple) and delegates to `handle_cast/2`. Inside `handle_cast/2`, the full event is fetched using `EventBus.fetch_event/1`, processed, and then marked as completed or skipped using `EventBus.mark_as_completed/1` or `EventBus.mark_as_skipped/1`. ```elixir defmodule EmailNotificationSubscriber do use GenServer def start_link(_) do GenServer.start_link(__MODULE__, nil, name: __MODULE__) end def init(_) do # Subscribe to user-related events EventBus.subscribe({__MODULE__, ["^user_.*"]}) {:ok, %{}} end # EventBus calls this with event shadow (topic + id tuple) def process({topic, id} = event_shadow) do GenServer.cast(__MODULE__, event_shadow) :ok end # Handle user registration events def handle_cast({:user_registered, id} = event_shadow, state) do # Fetch full event from ETS store event = EventBus.fetch_event(event_shadow) # Access event data %{email: email, name: name} = event.data # Perform work send_welcome_email(email, name) # Mark as completed (triggers cleanup if all subscribers done) EventBus.mark_as_completed({__MODULE__, event_shadow}) {:noreply, state} end # Handle events we don't care about def handle_cast({topic, id} = event_shadow, state) do # Mark as skipped (subscriber not interested in this event) EventBus.mark_as_skipped({__MODULE__, event_shadow}) {:noreply, state} end defp send_welcome_email(email, name) do # Implementation details... :ok end end # Subscriber with configuration defmodule DatabaseLogger do use GenServer def start_link(config) do GenServer.start_link(__MODULE__, config, name: __MODULE__) end def init(config) do # Subscribe with config tuple EventBus.subscribe({{__MODULE__, config}, [".*"]}) {:ok, config} end # Process receives config as first element def process({config, topic, id}) do GenServer.cast(__MODULE__, {config, topic, id}) :ok end def handle_cast({config, topic, id}, state) do event = EventBus.fetch_event({topic, id}) # Use config in processing save_to_database(config.database, event) # Mark completed with subscriber tuple subscriber = {__MODULE__, config} EventBus.mark_as_completed({subscriber, {topic, id}}) {:noreply, state} end defp save_to_database(db_url, event) do # Persist event... :ok end end ``` -------------------------------- ### Build EventBus.Model.Event Struct using Block Builder in Elixir Source: https://github.com/otobus/event_bus/blob/main/README.md Demonstrates how to use the `EventSource.build` block builder to construct an `EventBus.Model.Event` struct. The builder automatically sets `initialized_at` and `occurred_at` timestamps. Optional parameters like `transaction_id`, `ttl`, and `source` can be provided. The block passed to `build` should return the event data payload. ```elixir use EventBus.EventSource id = "some unique id" topic = :user_created transaction_id = "tx" # optional ttl = 600_000 # optional source = "my event creator" # optional params = %{id: id, topic: topic, transaction_id: transaction_id, ttl: ttl, source: source} EventSource.build(params) do # do some calc in here Process.sleep(1) # as a result return only the event data %{email: "jd@example.com", name: "John Doe"} end ``` ```elixir config :event_bus, topics: [], # list of atoms ttl: 30_000_000, # integer time_unit: :microsecond, # atom id_generator: EventBus.Util.Base62 # module: must implement 'unique_id/0' function ``` ```elixir # Without optional params params = %{topic: topic} EventSource.build(params) do %{email: "jd@example.com", name: "John Doe"} end ``` ```elixir # With optional error topic param params = %{id: id, topic: topic, error_topic: :user_create_erred} EventSource.build(params) do {:error, %{email: "Invalid format"}} end ``` -------------------------------- ### Implement Async Event Consumer with Poolboy in Elixir Source: https://github.com/otobus/event_bus/wiki/Creating-Event-Consumers This Elixir code defines a GenServer consumer that utilizes the :poolboy library to manage a worker pool for processing events. It handles event fetching, processing, and marking them as completed. Dependencies include GenServer and Logger. It takes an event tuple {topic, id} as input and returns {:ok, []} from init. ```elixir defmodule MyFifthConsumer do @moduledoc false use GenServer require Logger ## Public API @doc """ Read data from cache. """ def process({_topic, _id} = event_shadow) do :poolboy.transaction(:worker_pool, fn(worker) -> GenServer.cast(worker, {:perform, event_shadow}) end) end ## Callbacks @doc false def start_link(_opts) do GenServer.start_link(__MODULE__, []) end @doc false def init(_opts) do {:ok, []} end @doc false def handle_cast({:perform, {topic, id}}, state) do # Fetch event event = EventBus.fetch_event({topic, id}) # Do sth with the event # Or just log for the sample Logger.info("I am handling the event with :poolboy #{__MODULE__}") Logger.info(fn -> inspect(event) end) EventBus.mark_as_completed({MyFifthConsumer, topic, id}) {:noreply, state} end end ``` -------------------------------- ### Build Events with EventSource in Elixir Source: https://context7.com/otobus/event_bus/llms.txt Use EventSource macros to automatically set timing fields (initialized_at, occurred_at) and ID generation when building events. The code block within EventSource.build/2 executes the main logic, and its return value becomes the event's data. Configuration for topics, TTL, time unit, and ID generator is typically done in config.exs. Error handling can be managed using an error_topic. ```elixir defmodule UserService do use EventBus.EventSource # Configure EventBus defaults in config.exs # config :event_bus, # topics: [:user_created, :user_create_failed], # ttl: 30_000_000, # 30 seconds in microseconds # time_unit: :microsecond, # id_generator: EventBus.Util.Base62 def create_user(params) do # Build event with automatic timing and ID generation event = EventSource.build(%{topic: :user_created}) do # Perform the actual work inside the block Process.sleep(10) # Simulate database operation # Return value becomes event.data %{user_id: 123, email: params[:email], created_at: DateTime.utc_now()} end # Event automatically includes: # - id: generated via configured id_generator # - initialized_at: timestamp when build/2 was called # - occurred_at: timestamp when block completed # - source: "UserService" (auto-detected from module name) # - ttl: from config # => %Event{ # id: "Ewk7fL6Erv0vsW6S", # topic: :user_created, # data: %{user_id: 123, email: "...", created_at: ~U[...]}, # initialized_at: 1703260800000000, # occurred_at: 1703260800010000, # source: "UserService", # ttl: 30_000_000, # transaction_id: "Ewk7fL6Erv0vsW6S" # } EventBus.notify(event) event.data end def register_user_with_validation(params) do # Use error_topic to handle failures EventSource.notify(%{ topic: :user_created, error_topic: :user_create_failed, transaction_id: "txn_" <> Integer.to_string(:rand.uniform(10000)) }) do case validate_email(params[:email]) do :ok -> {:email => params[:email], :status => "active"} {:error, reason} -> # Returning {:error, ...} triggers error_topic {:error, %{reason: reason, email: params[:email]}} end end # On success: notifies :user_created with data # On error: notifies :user_create_failed with {:error, ...} # Returns only the data portion end defp validate_email(email) do if String.contains?(email, "@"), do: :ok, else: {:error, "Invalid email"} end end ``` -------------------------------- ### Subscribe Consumer to Multiple Topics - Elixir Source: https://github.com/otobus/event_bus/wiki/Subscribing-Consumers-to-Topic(s) Subscribes a consumer to multiple specific topics, like ':user_registered' and ':email_sent'. Each topic is defined with an exact match regex. The subscriber and the list of topic patterns are passed to EventBus.subscribe. ```elixir subscriber = MyFirstConsumer topics = ["^user_registed$", "^email_sent$"] EventBus.subscribe({subscriber, topics}) ``` -------------------------------- ### Create and Emit an Event with EventBus (Elixir) Source: https://github.com/otobus/event_bus/wiki/Emitting-(Dispatching)-an-Event This snippet demonstrates how to construct a basic event object using the EventBus.Model.Event structure with mandatory attributes such as a unique ID, a topic, and event data. It then shows how to emit this event using the EventBus.notify function. Ensure the 'uuid' library is added if you prefer using UUIDs for event IDs. ```elixir # Build the event structure event = %EventBus.Model.Event{ id: EventBus.Util.Base62.unique_id(), # If you add `uuid` library then good to use `UUID.uuid4()`. topic: :user_created, data: %{email: "sample@example.com", ...} # an aggregated data for the event } # Emit the event EventBus.notify(event) > 23:49:27.316 [warn] Topic(:user_created) doesn't have subscribers > :ok ``` -------------------------------- ### Subscribe to All Event Topics Source: https://github.com/otobus/event_bus/blob/main/README.md Allows subscribing to all event topics using a wildcard pattern. The subscriber is expected to be a module that handles event reception. No external dependencies are explicitly mentioned, and the input is a subscriber module and a list of topics. ```elixir EventBus.subscribe({MyEventSubscriber, ["*"]}) ``` -------------------------------- ### Subscribe Consumer to All Topics - Elixir Source: https://github.com/otobus/event_bus/wiki/Subscribing-Consumers-to-Topic(s) Subscribes a given consumer to all registered topics in the event bus. It uses a wildcard regex '.*' to match any topic name. The subscriber module and a list of topic patterns are passed as a tuple to the EventBus.subscribe function. ```elixir subscriber = MyFirstConsumer topics = [".*"] EventBus.subscribe({subscriber, topics}) ``` -------------------------------- ### Configure event_bus_metrics Settings Source: https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI Configure the event_bus_metrics settings in your config.exs file. These settings control cross-origin requests, HTTP server behavior, port, and the frequency of Server-Sent-Events tickers for metrics. ```elixir config :event_bus_metrics, cross_origin: {:system, "EB_CROSS_ORIGIN", "off"}, http_server: {:system, "EB_HTTP_SERVER", "off"}, http_server_port: {:system, "PORT", "4000"}, # Server-Sent-Events Tickers: notify_subscriber_metrics_in_ms: {:system, "EB_SUBSCRIBER_M_IN_MS", 250}, notify_topic_metrics_in_ms: {:system, "EB_TOPIC_M_IN_MS", 1000}, notify_topics_metrics_in_ms: {:system, "EB_TOPICS_M_IN_MS", 250} ``` -------------------------------- ### Subscribe to EventBus Topics with Regex in Elixir Source: https://context7.com/otobus/event_bus/llms.txt Register subscribers to receive event notifications based on topic patterns. Supports wildcard subscriptions, exact topic matching using regex, and configuration for stateful subscribers. Functions are available to subscribe, unsubscribe, check subscription status, and list all subscribers. ```elixir # Subscribe to all events using wildcard pattern EventBus.subscribe({MyEventSubscriber, [".*"]}) # => :ok # Subscribe to specific topic patterns with regex EventBus.subscribe({PaymentSubscriber, ["payment_.*", "refund_.*"]}) # => :ok # Subscribe with exact topic matching EventBus.subscribe({OrderSubscriber, ["^order_shipped$", "^order_cancelled$"]}) # => :ok # Subscribe with configuration (for stateful subscribers) config = %{database: "postgresql://localhost/mydb", batch_size: 100} subscriber = {DatabaseLogger, config} EventBus.subscribe({subscriber, [".*"]}) # => :ok # Unsubscribe a simple subscriber EventBus.unsubscribe(MyEventSubscriber) # => :ok # Unsubscribe a configured subscriber EventBus.unsubscribe({DatabaseLogger, config}) # => :ok # Check if subscriber is registered with specific patterns EventBus.subscribed?({PaymentSubscriber, ["payment_.*"]}) # => true # List all subscribers EventBus.subscribers() # => [MyEventSubscriber, PaymentSubscriber, {DatabaseLogger, %{...}}] # List subscribers for a specific topic EventBus.subscribers(:payment_processed) # => [MyEventSubscriber, PaymentSubscriber] ``` -------------------------------- ### Elixir Event Subscriber Processing Logic Source: https://github.com/otobus/event_bus/blob/main/README.md Demonstrates how to implement subscriber logic in Elixir for the EventBus. It covers processing events with and without configuration, and handling different event statuses like 'bye_received', 'hello_received', and general topics. Includes calls to EventBus for fetching and marking event completion or skipping. ```elixir defmodule MyEventSubscriber do ... # if your subscriber does not have a config def process({topic, id} = event_shadow) do GenServer.cast(__MODULE__, event_shadow) :ok end ... # if your subscriber has a config def process({config, topic, id} = event_shadow_with_conf) do GenServer.cast(__MODULE__, event_shadow_with_conf) :ok end ... # if your subscriber does not have a config def handle_cast({:bye_received, id} = event_shadow, state) do event = EventBus.fetch_event(event_shadow) # do sth with event # update the watcher! # version >= 1.4.0 EventBus.mark_as_completed({__MODULE__, event_shadow}) # all versions EventBus.mark_as_completed({__MODULE__, :bye_received, id}) ... {:noreply, state} end def handle_cast({:hello_received, id} = event_shadow, state) do event = EventBus.fetch_event({:hello_received, id}) # do sth with EventBus.Model.Event # update the watcher! # version >= 1.4.0 EventBus.mark_as_completed({__MODULE__, event_shadow}) # all versions EventBus.mark_as_completed({__MODULE__, :hello_received, id}) ... {:noreply, state} end def handle_cast({topic, id} = event_shadow, state) do # version >= 1.4.0 EventBus.mark_as_skipped({__MODULE__, event_shadow}) # all versions EventBus.mark_as_skipped({__MODULE__, topic, id}) {:noreply, state} end ... # if your subscriber has a config def handle_cast({config, :bye_received, id}, state) do event = EventBus.fetch_event({:bye_received, id}) # do sth with event # update the watcher! subscriber = {__MODULE__, config} EventBus.mark_as_completed({subscriber, :bye_received, id}) ... {:noreply, state} end def handle_cast({config, :hello_received, id}, state) do event = EventBus.fetch_event({:hello_received, id}) # do sth with EventBus.Model.Event # update the watcher! subscriber = {__MODULE__, config} EventBus.mark_as_completed({subscriber, :hello_received, id}) ... {:noreply, state} end def handle_cast({config, topic, id}, state) do subscriber = {__MODULE__, config} EventBus.mark_as_skipped({subscriber, topic, id}) {:noreply, state} end ... end ``` -------------------------------- ### Server-Sent-Events (SSE) Metrics Stream Source: https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI Stream live metrics using Server-Sent Events. ```APIDOC ## GET /event_bus/sse ### Description Streaming endpoint for live metrics using Server-Sent Events. ### Method GET ### Endpoint /event_bus/sse ### Parameters None ### Request Example None ### Response #### Success Response (200) - Server-Sent Events stream containing live metrics updates. #### Response Example ``` data: {"type": "topic_metrics", "payload": {"topic_name": "example_topic", "count": 10}} data: {"type": "subscriber_metrics", "payload": {"subscriber_name": "example_subscriber", "processed_count": 5}} ``` ``` -------------------------------- ### Topic Management API Source: https://context7.com/otobus/event_bus/llms.txt Manage event topics within the EventBus. This includes registering new topics, unregistering existing ones, checking for topic existence, and listing all registered topics. ```APIDOC ## Topic Management API ### Description APIs for managing event topics within the EventBus. ### Register Topics ```elixir # Register topics at application startup config :event_bus, topics: [:user_registered, :payment_processed, :order_shipped] # Register topics dynamically at runtime EventBus.register_topic(:webhook_received) # => :ok ``` ### Unregister Topic ```elixir # Unregister a topic (warning: deletes associated ETS tables) EventBus.unregister_topic(:webhook_received) # => :ok ``` ### Check Topic Existence ```elixir # Check if a topic exists EventBus.topic_exist?(:user_registered) # => true ``` ### List All Topics ```elixir # List all registered topics EventBus.topics() # => [:user_registered, :payment_processed, :order_shipped] ``` ``` -------------------------------- ### Notify Event Data to Topic using Block Notifier in Elixir Source: https://github.com/otobus/event_bus/blob/main/README.md Illustrates how to use the `EventSource.notify` block notifier to send event data to a specified topic. Similar to the builder, it automatically sets timestamps and accepts optional parameters. The block executed by `notify` should return the event data. If the block returns an error tuple, the `error_topic` parameter will be used for event creation. ```elixir use EventBus.EventSource id = "some unique id" topic = :user_created error_topic = :user_create_erred # optional (in case error tuple return in yield execution, it will use :error_topic value as :topic for event creation) transaction_id = "tx" # optional ttl = 600_000 # optional source = "my event creator" # optional EventBus.register_topic(topic) # in case you didn't register it in `config.exs` params = %{id: id, topic: topic, transaction_id: transaction_id, ttl: ttl, source: source, error_topic: error_topic} EventSource.notify(params) do # do some calc in here # as a result return only the event data %{email: "mrsjd@example.com", name: "Mrs Jane Doe"} end ``` -------------------------------- ### Create and Notify Events in Elixir using EventBus Source: https://context7.com/otobus/event_bus/llms.txt Construct event structures with required and optional traceability fields, then publish them to notify matching subscribers. The library allows creating events with basic data or comprehensive traceability information including transaction IDs, timestamps, source, and TTL. ```elixir alias EventBus.Model.Event # Create a simple event with required fields only event = %Event{ id: "evt_001", topic: :user_registered, data: %{user_id: 42, email: "user@example.com", name: "Jane Doe"} } # Notify all subscribers of the event EventBus.notify(event) # => :ok # Create an event with all optional traceability fields full_event = %Event{ id: "evt_002", transaction_id: "txn_abc123", topic: :payment_processed, data: %{amount: 99.99, currency: "USD", payment_method: "credit_card"}, initialized_at: 1703260800000000, # microseconds occurred_at: 1703260800050000, source: "PaymentService.process/2", ttl: 3600000000 # 1 hour in microseconds } EventBus.notify(full_event) # => :ok # Event with keyword list data event_with_keywords = %Event{ id: "evt_003", topic: :order_shipped, data: [order_id: 1234, tracking_number: "TRK789XYZ", carrier: "FedEx"] } EventBus.notify(event_with_keywords) # => :ok ``` -------------------------------- ### Register EventBus Topics in Elixir Source: https://context7.com/otobus/event_bus/llms.txt Configure and manage event topics for distribution within your Elixir application. Topics can be registered statically in configuration files or dynamically at runtime. The library provides functions to register, unregister, check existence, and list all topics. ```elixir config :event_bus, topics: [:user_registered, :payment_processed, :order_shipped] # Or register topics dynamically at runtime EventBus.register_topic(:webhook_received) # => :ok # Unregister a topic (warning: deletes associated ETS tables) EventBus.unregister_topic(:webhook_received) # => :ok # Check if a topic exists EventBus.topic_exist?(:user_registered) # => true # List all registered topics EventBus.topics() # => [:user_registered, :payment_processed, :order_shipped] ``` -------------------------------- ### Subscribe to Specific Event Topics Source: https://github.com/otobus/event_bus/blob/main/README.md Enables subscribing to a predefined set of specific event topics. This is useful for fine-grained control over event handling. The input includes the subscriber module and a list of topic patterns. ```elixir EventBus.subscribe({MyEventSubscriber, ["purchase_", "booking_confirmed$", "flight_passed$"]}) ``` -------------------------------- ### Subscribe Consumer to Specific Topic - Elixir Source: https://github.com/otobus/event_bus/wiki/Subscribing-Consumers-to-Topic(s) Subscribes a consumer to a single, specific topic, such as ':user_registered'. It uses an exact match regex '^user_registered$' to ensure only that topic is subscribed. The subscriber module and the topic pattern list are provided to EventBus.subscribe. ```elixir subscriber = MyFirstConsumer topics = ["^user_registered$"] EventBus.subscribe({subscriber, topics}) ``` -------------------------------- ### EventBus Subscription API Source: https://github.com/otobus/event_bus/blob/main/README.md APIs for subscribing to and unsubscribing from the event bus. ```APIDOC ## EventBus Subscription and Unsubscription ### Description Allows clients to subscribe to specific event topics or all topics, and to unsubscribe from them. Subscribers can be defined with or without a configuration. ### Method `EventBus.subscribe/1`, `EventBus.unsubscribe/1` ### Parameters #### Subscribe Parameters - **subscriber** (tuple or module) - The subscriber module or a tuple containing the subscriber module and its configuration. - **topics** (list of strings) - A list of topics to subscribe to. `".*"` subscribes to all topics. #### Unsubscribe Parameters - **subscriber** (tuple or module) - The subscriber module or a tuple containing the subscriber module and its configuration. ### Request Example (Subscription) ```elixir # Subscribe to all topics EventBus.subscribe({MyEventSubscriber, [".*"]}) # Subscribe to specific topics EventBus.subscribe({MyEventSubscriber, ["purchase_", "booking_confirmed$"]}) # Subscribe with a configuration config = %{} subscriber = {MyEventSubscriber, config} EventBus.subscribe({subscriber, [".*"]}) ``` ### Request Example (Unsubscription) ```elixir # Unsubscribe EventBus.unsubscribe(MyEventSubscriber) # Unsubscribe with a configuration config = %{} EventBus.unsubscribe({MyEventSubscriber, config}) ``` ### Response #### Success Response (200) - **status** (atom) - `:ok` indicating successful subscription or unsubscription. #### Response Example ```elixir :ok ``` ``` -------------------------------- ### Register Event Bus Topics On Demand Source: https://github.com/otobus/event_bus/wiki/Creating-(Registering)-Topics Topics can be registered dynamically at any point in the application's lifecycle using the `EventBus.register_topic/1` function. This function accepts a single atom representing the topic name. This method is useful for registering topics that are specific to certain parts of the application or environment. ```elixir EventBus.register_topic(:user_created) EventBus.register_topic(:user_activated) EventBus.register_topic(:email_sent) ... ``` -------------------------------- ### EventBus Metrics UI Source: https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI Access the graphical user interface for EventBus metrics. The URL path must end with a '/' character. ```APIDOC ## EventBus Metrics UI ### Description Access the graphical user interface for EventBus metrics. The URL path must end with a '/' character. ### Method GET ### Endpoint /event_bus/ui/ ### Parameters None ### Request Example None ### Response #### Success Response (200) - HTML content for the metrics UI #### Response Example None ``` -------------------------------- ### EventBus Management API Source: https://github.com/otobus/event_bus/blob/main/README.md APIs for managing and querying subscribers and topics within the event bus. ```APIDOC ## EventBus Management ### Description Provides functionalities to list all subscribers, list subscribers for a specific event, and check for the existence of a topic. ### Method `EventBus.subscribers/0`, `EventBus.subscribers/1`, `EventBus.topic_exist?/1` ### Parameters #### `subscribers/1` Parameters - **event_topic** (atom) - The topic for which to list subscribers. #### `topic_exist?/1` Parameters - **topic** (atom) - The topic to check for existence. ### Request Example (List Subscribers) ```elixir # List all subscribers EventBus.subscribers() # List subscribers for a specific event topic EventBus.subscribers(:hello_received) ``` ### Request Example (Topic Existence) ```elixir # Check if a topic exists EventBus.topic_exist?(:metrics_updated) ``` ### Response #### Success Response (200) - **List Subscribers**: A list of subscribers, potentially nested with their configurations and subscribed topics. - **Topic Existence**: A boolean (`true` or `false`) indicating if the topic exists. #### Response Example (List Subscribers) ```elixir # All subscribers [{MyEventSubscriber, [".*"]}, {{AnotherSubscriber, %{}}, [".*"]}] # Subscribers for a specific event [MyEventSubscriber, {{AnotherSubscriber, %{}}}] ``` #### Response Example (Topic Existence) ```elixir false ``` ``` -------------------------------- ### Elixir Persistent Event Data Storage Subscription Source: https://github.com/otobus/event_bus/blob/main/README.md Illustrates how to subscribe to all event types using a wildcard topic and implement a data store subscriber in Elixir. This pattern is used for saving event data to a persistent store. ```elixir EventBus.subscribe({MyDataStore, [".*"]}) # then in your data store save the event defmodule MyDataStore do ... def process({topic, id} = event_shadow) do GenServer.cast(__MODULE__, event_shadow) :ok end ... def handle_cast({topic, id}, state) do event = EventBus.fetch_event({topic, id}) # write your logic to save event_data to a persistent store EventBus.mark_as_completed({__MODULE__, {topic, id}}) {:noreply, state} end end ``` -------------------------------- ### Subscriber Management API Source: https://context7.com/otobus/event_bus/llms.txt Manage event subscribers for the EventBus. This includes subscribing with various patterns (wildcard, regex, exact), unsubscribing, checking subscription status, and listing subscribers. ```APIDOC ## Subscriber Management API ### Description APIs for managing event subscribers within the EventBus. ### Subscribe to Topics ```elixir # Subscribe to all events using wildcard pattern EventBus.subscribe({MyEventSubscriber, [".*"]}) # => :ok # Subscribe to specific topic patterns with regex EventBus.subscribe({PaymentSubscriber, ["payment_.*", "refund_.*"]}) # => :ok # Subscribe with exact topic matching EventBus.subscribe({OrderSubscriber, ["^order_shipped$", "^order_cancelled$"]}) # => :ok # Subscribe with configuration (for stateful subscribers) config = %{database: "postgresql://localhost/mydb", batch_size: 100} subscriber = {DatabaseLogger, config} EventBus.subscribe({subscriber, [".*"]}) # => :ok ``` ### Unsubscribe ```elixir # Unsubscribe a simple subscriber EventBus.unsubscribe(MyEventSubscriber) # => :ok # Unsubscribe a configured subscriber EventBus.unsubscribe({DatabaseLogger, config}) # => :ok ``` ### Check Subscription Status ```elixir # Check if subscriber is registered with specific patterns EventBus.subscribed?({PaymentSubscriber, ["payment_.*"]}) # => true ``` ### List Subscribers ```elixir # List all subscribers EventBus.subscribers() # => [MyEventSubscriber, PaymentSubscriber, {DatabaseLogger, %{...}}] # List subscribers for a specific topic EventBus.subscribers(:payment_processed) # => [MyEventSubscriber, PaymentSubscriber] ``` ``` -------------------------------- ### List Subscribers for a Specific Event Topic Source: https://github.com/otobus/event_bus/blob/main/README.md Fetches a list of subscribers that are registered for a particular event topic. This helps in identifying which modules are listening to a specific event. ```elixir EventBus.subscribers(:hello_received) ``` -------------------------------- ### List All Subscribers Source: https://github.com/otobus/event_bus/blob/main/README.md Retrieves a list of all currently subscribed modules and their associated topics. This function is useful for monitoring and debugging the event subscription status. ```elixir EventBus.subscribers() ```