Seqy

Hex.pm Version

Seqy is an events sequentializer. Need to process events in a specific order? Seqy can help.

Under Seqy's Hood

graph TD
    A[Seqy] --> B(Seqy.Processbook)
    A --> C[topic_1_supervisor]
    A --> D[topic_2_supervisor]
    C --> E[topic_1_queue_1]
    C --> F[topic_1_queue_2]

When Seqy is started, it also starts Seqy.Processbook and a supervisor for each sequence topic configured.

Seqy.Processbook is responsible for storing the pid of the process that would handle the processing of a specific event queue. Once you enqueue an event, Seqy would check in the processbook if there's an active handler for the specific queue_id. If there's none, Seqy would start an instance of the handler under the corresponding topic supervisor. When all the events are exhausted, the handler for the specific queue would terminate.

Installation

Add seqy as a dependency on your mix.exs file.

def deps do
  [
    {:seqy, "~> 0.1.0"}
  ]
end

Configuration

To make Seqy work, you need to define the topic of the sequence, event actions (in order) and handler module.

config :seqy,
  topics: [
    %{
      name: :user_purchase,
      actions: [:"user.created", :"user.purchased", :"user.paid"],
      handler: MyApp.EventHandler
    }
  ]

actions should have the desired order for processing the events.

Usage

Before enqueueing events with Seqy, you need to define a handler for the topic. To define a handler, create a module that use the Seqy.Handler module. Then, implement the handle/1 callback for each event you expect in the sequence.

defmodule MyApp.EventHandler do
  use Seqy.Handler

  require Logger

  def handle(%Seqy.Event{action: :"user.created", args: %{user_id: user_id}}) do
    Logger.info("#{user_id} has been created.")
  end

  def handle(%Seqy.Event{action: :"user.purchased", args: %{user_id: user_id}}) do
    Logger.info("#{user_id} has purchased an item.")
  end

  def handle(%Seqy.Event{action: :"user.paid", args: %{user_id: user_id}}) do
    Logger.info("#{user_id} has paid.")
  end
end

With the event handler ready, we can start enqueueing events to Seqy.

%{action: :"user.created", queue_id: "user_id:1", topic: :user_purchase, args: %{user_id: 1}}
|> Seqy.new()
|> Seqy.enqueue()

An event should have the ff: