Belay.Migrate.Oban (Belay v1.0.0)

Copy Markdown View Source

Move an Oban installation's pending work into Belay.

Converts available, scheduled, and retryable rows from oban_jobs into ready Belay jobs (scheduled/retryable keep their scheduled_at as ready_at). Everything else is deliberately left alone:

  • executing rows are flagged, never migrated — they may be mid-run on a live Oban node. Stop or drain Oban first.

  • Terminal rows (completed, discarded, cancelled) are history, not work. Migrating them would produce journal-less, cost-less rows that pollute Belay's metrics while buying nothing. Keep the old table read-only until your retention window lapses, then drop it:

    ALTER TABLE oban_jobs RENAME TO oban_jobs_archive;

Runs are idempotent: each migrated row carries meta.migrated_from_oban_id, and re-runs skip ids already present.

Uniqueness cannot be inferred — Oban stores unique policy on the worker, Belay stores unique keys on rows. The analyzer lists workers whose pending rows may need unique: re-declared at their insert sites.

Used by mix belay.migrate_oban; callable directly:

{:ok, conn} = Postgrex.start_link(...)
report = Belay.Migrate.Oban.analyze(conn)
Belay.Migrate.Oban.execute(conn, report)

Summary

Functions

Inspect oban_jobs and return a migration report (no writes).

Migrate the pending rows described by analyze/2's report. Returns %{migrated: n, skipped_existing: n}. Only workers that resolve to a Belay worker module are migrated unless force: true.

Functions

analyze(conn, opts \\ [])

@spec analyze(
  GenServer.server(),
  keyword()
) :: map()

Inspect oban_jobs and return a migration report (no writes).

Options: :mapping%{"Old.Worker" => "New.Worker"} kind renames.

execute(conn, report, opts \\ [])

@spec execute(GenServer.server(), map(), keyword()) :: %{
  migrated: non_neg_integer(),
  skipped_existing: non_neg_integer()
}

Migrate the pending rows described by analyze/2's report. Returns %{migrated: n, skipped_existing: n}. Only workers that resolve to a Belay worker module are migrated unless force: true.