Mailglass.Oban.TenancyMiddleware (Mailglass v0.1.0)

Copy Markdown View Source

Serializes Mailglass.Tenancy.current/0 across Oban job boundaries (D-33).

Enqueue side

Phase 3 Mailglass.Outbound adds a put_tenant_in_args/2 helper that merges %{"mailglass_tenant_id" => current()} into job args at enqueue time. The serialized value is a plain string — JSON-safe, no coercion.

Perform side

Two equivalent integration paths — both converge on Mailglass.Tenancy.with_tenant/2.

OSS Oban (wrap_perform/2)

OSS Oban 2.21 has no middleware behaviour. Adopters wrap their worker's perform/1 body:

defmodule MyApp.MailerWorker do
  use Oban.Worker

  @impl Oban.Worker
  def perform(job) do
    Mailglass.Oban.TenancyMiddleware.wrap_perform(job, fn ->
      # ... worker body; Mailglass.Tenancy.current/0 now returns
      # the tenant stamped at enqueue time.
      :ok
    end)
  end
end

Oban Pro (call/2)

Oban Pro's Oban.Middleware behaviour invokes call/2. The shape this module exports matches the documented behaviour (job + next/1 continuation) so Pro adopters register it directly:

config :my_app, Oban,
  engine: Oban.Engines.Basic,
  middleware: [Mailglass.Oban.TenancyMiddleware],
  queues: [mailglass: 10]

Contract

  • job.args["mailglass_tenant_id"] present and binary → wrap in Mailglass.Tenancy.with_tenant/2.
  • Key missing or non-binary → pass through unchanged. Lets adopters phase in the middleware without breaking existing jobs.
  • If the wrapped body raises, the prior tenant stamp is restored before the raise propagates (inherited from Mailglass.Tenancy.with_tenant/2).

Summary

Functions

Oban-Pro-compatible middleware entry point.

Wraps fun in Mailglass.Tenancy.with_tenant/2 when job.args carries a binary "mailglass_tenant_id". Pass-through otherwise.

Functions

call(job, next)

(since 0.1.0)
@spec call(map(), (map() -> any())) :: any()

Oban-Pro-compatible middleware entry point.

next/1 is the continuation supplied by Pro's middleware stack; receives the job and returns the perform result. For OSS adopters, prefer wrap_perform/2.

wrap_perform(map, fun)

(since 0.1.0)
@spec wrap_perform(map(), (-> any())) :: any()

Wraps fun in Mailglass.Tenancy.with_tenant/2 when job.args carries a binary "mailglass_tenant_id". Pass-through otherwise.

This is the OSS-Oban-friendly integration surface — adopters invoke it from inside their perform/1. fun is zero-arity; the job struct is available in the closure the caller constructs.