By default, Chimeway uses a synchronous dispatcher that attempts to deliver notifications immediately when they are triggered. For production environments, it is highly recommended to process these deliveries asynchronously in the background.
Chimeway provides native integration with Oban, the leading background job system for Elixir.
Prerequisites
- Add Oban to your project if you haven't already:
defp deps do [ {:oban, "~> 2.17"} ] end - Configure Oban in your application (see Oban's installation guide for full details).
Configuring Chimeway for Oban
To tell Chimeway to use Oban for async dispatch, update your application configuration:
# config/config.exs
config :chimeway,
dispatcher: Chimeway.Dispatch.ObanWhen you use the Chimeway.Dispatch.Oban dispatcher, Chimeway will automatically convert delivery plans into Oban jobs instead of executing them synchronously.
Setting Up the Queues and Workers
Chimeway uses several queues to handle different background tasks. Update your Oban configuration to include these queues:
# config/config.exs
config :my_app, Oban,
repo: MyApp.Repo,
plugins: [
Oban.Plugins.Pruner,
# Configure the ProgressionWorker to run periodically (e.g., every minute)
{Oban.Plugins.Cron,
crontab: [
{"* * * * *", Chimeway.Workflows.Workers.ProgressionWorker}
]}
],
queues: [
default: 10,
chimeway_delivery: [limit: 20], # For async dispatch of notifications
chimeway_signals: [limit: 10], # For processing workflow signals
chimeway_workflows: [limit: 5] # For general workflow progression tasks (if any)
]Workflow Engine Workers
If you are using Chimeway's Workflow Engine for multi-step journeys (like wait gates and escalations), you need to configure Oban to process two specific workers:
-
Chimeway.Workflows.Workers.ProgressionWorker: This worker is responsible for evaluating wait gates. When a workflow enters a wait step, it pauses. TheProgressionWorkermust be scheduled to run periodically (e.g., every minute usingOban.Plugins.Cronas shown above) to check for expired wait steps and resume progression. -
Chimeway.Workflows.Workers.SignalRouterWorker: When your application emits signals (e.g., "user viewed notification") viaChimeway.Signal.track/4, the engine enqueues a job for theSignalRouterWorker. This worker processes the signal in the background (using thechimeway_signalsqueue) to see if it satisfies any active stop conditions, preventing slow web requests when tracking user feedback.
Transactional Enqueueing for Consistency
One of the major benefits of using Oban with Chimeway is transactional consistency. Because both Chimeway and Oban use Ecto and Postgres, you can guarantee that if a transaction commits, the notification will be enqueued, and if it rolls back, the notification won't be sent.
When triggering notifications, you can pass an Ecto.Multi struct to the trigger options. Chimeway will insert the delivery records and enqueue the Oban jobs within the same database transaction.
alias Ecto.Multi
alias MyApp.Repo
# Start a multi transaction
Multi.new()
# ... do your application work (e.g., create a user) ...
|> Multi.insert(:user, %MyApp.User{name: "Alice", email: "alice@example.com"})
# Pass the multi to Chimeway
|> Multi.run(:notification, fn repo, %{user: user} ->
WelcomeNotifier.trigger(
user.id,
%{name: user.name},
# Ensure deliveries are saved and enqueued inside the Multi
multi: multi
)
# When using the multi option, trigger/3 returns {:ok, multi}
end)
|> Repo.transaction()If the transaction succeeds, all deliveries are guaranteed to be in the chimeway_delivery queue, ready for async processing by Oban. If the transaction fails, no jobs are enqueued.