View Source Migrating from Other Languages
Migrating background jobs to Elixir is easy with Oban because everything lives in your PostgreSQL
database. Oban relies on a structured oban_jobs
table as its job queue, and purposefully uses
JSON as a portable data structures for serialization. That makes enqueueing jobs into Oban simple for
any language with a PostgreSQL adapter—no Oban client necessary.
Use Case: Inserting Jobs from Rails
It's no secret that Ruby to Elixir is a common migration path for developers and existing applications alike. Let's explore how to write an adapter for inserting Oban jobs from a Rails application.
To start, define a skeletal ActiveRecord
model with a few conveniences for scheduling jobs:
class Oban::Job < ApplicationRecord
# This column is in use, but not used for the insert workflow.
self.ignored_columns = %w[errors]
# A simple wrapper around `create` that ensures the job is scheduled immediately.
def self.insert(worker:, args: {}, queue: "default", scheduled_at: nil)
create(
worker: worker,
queue: queue,
args: args,
scheduled_at: scheduled_at || Time.now.utc,
state: scheduled_at ? "scheduled" : "available"
)
end
end
The insert
class method is a convenience that uses named arguments to force passing a worker
while providing some defaults. The only semi-magical thing within insert
is determining the
correct state for scheduled jobs. In Oban, jobs that are ready to execute have an available
state, while jobs slated for the future are scheduled
.
To insert a single job using the insert
class method:
Oban::Job.insert(worker: "MyWorker", args: {id: 1}, queue: "default")
Provided your Elixir application has a worker named MyWorker
and the default
queue is running,
Oban will pick up and execute the job immediately. To schedule the job to run a minute in the
future instead, pass a scheduled_at
timestamp:
Oban::Job.insert(worker: "MyWorker", args: {id: 1}, scheduled_at: 1.minute.from_now.utc)
Now, if you're using Rails 6+, you can also use insert_all
to batch insert jobs:
Oban::Job.insert_all([
{worker: "MyWorker", args: {id: 1}, queue: "default"},
{worker: "MyWorker", args: {id: 2}, queue: "default"},
{worker: "MyWorker", args: {id: 3}, queue: "default"},
])
Safety Guaranteed
Most columns in oban_jobs
have sensible defaults, so only the worker
and args
are typically
required. For integrity, all required columns are marked as NON NULL
, and several have CHECK
constraints as well for extra enforcement.
That's all you need to start migrating background jobs from Rails to Elixir (if you're using Oban, that is). Naturally, the same pattern would work for Python, Node, PHP, or any other language with a Postgres adapter.