Relays messages into Oban as jobs.
This module only exists when :oban is in your dependencies.
{Outboxer,
repo: MyApp.Repo,
outboxes: [
emails: [relay: {Outboxer.Relay.Oban, worker: MyApp.Workers.SendEmail, job_opts: [queue: :mailers]}]
]}Options
:worker- Required. TheOban.Workermodule that handles the message, or a function taking the envelope and returning one.:oban(atom/0) - Name of the Oban instance to insert into. The default value isOban.:payload- How the payload is placed in the job args under"payload".:jsondecodes it (use with the default message encoding),:rawpasses the string through,:base64encodes binary payloads. The default value is:json.:args- A function taking the envelope and returning the job args map. Replaces the default args entirely. The default value isnil.:job_opts- Options forOban.Worker.new/2(:queue,:priority,:max_attempts, ...), or a function taking the envelope and returning them. The default value is[].
Job args
Unless you pass :args, a job gets:
%{
"id" => "emails-42", # Outboxer.Envelope.dedup_id/1
"type" => "MyApp.Events.Welcome",
"group_key" => "user:7", # or nil
"headers" => %{},
"payload" => %{"user_id" => 7} # see the :payload option
}Do you need an outbox in front of Oban?
Often you do not. Oban.insert/2 inside your own transaction is already
transactional when Oban uses the same repo, and it is one moving part
fewer. Reach for this relay when:
- Oban lives in a different database than the business data, so the job insert cannot join your transaction.
- You want jobs enqueued in order per group (see below).
- Your code publishes domain messages and should not know which of them end up as jobs, in Kafka, or both.
Guarantees
When Outboxer and Oban use the same Postgres repo, the job insert joins
the batch transaction: jobs are inserted and outbox rows removed
atomically, so a message becomes exactly one job. In every other setup
(different repos, SQLite) the handoff is at-least-once and a job may be
inserted twice; add an Oban unique constraint on the "id" arg through
:job_opts if that matters.
Ordering
Outboxer inserts jobs in order, so job ids follow message order within a
group. Oban executes them in that order only when the queue runs one job
at a time (queues: [mailers: 1]) on a single node, or with Oban Pro's
partitioned queues. With ordinary concurrency, jobs run in parallel.