Skip to content

trax-retail/gen_queue_oban

Repository files navigation

GenQueue Oban

Build Status GenQueue Oban Version

This is an adapter for GenQueue to enable functionality with Oban.

Installation

The package can be installed by adding gen_queue_oban to your list of dependencies in mix.exs:

def deps do
  [
    {:gen_queue_oban, "~> 0.1.0"}
  ]
end

Documentation

See HexDocs for additional documentation.

Configuration

Before starting, please refer to the Oban documentation for details on configuration. This adapter handles zero Oban related config.

Creating Enqueuers

We can start off by creating a new GenQueue module, which we will use to push jobs to Oban.

defmodule Enqueuer do
  use GenQueue, otp_app: :my_app
end

Once we have our module setup, ensure we have our config pointing to the GenQueue.Adapters.Oban adapter.

config :my_app, Enqueuer, [
  adapter: GenQueue.Adapters.Oban
]

Starting Enqueuers

By default, gen_queue_oban does not start Oban on application start. So we must add our new Enqueuer module to our supervision tree.

  children = [
    supervisor(Enqueuer, []),
  ]

Creating Jobs

Jobs are simply modules with a perform method. With Oban we must add use Oban.Worker to our jobs with the relevant configuration.

defmodule MyJob do
  use Oban.Worker, queue: "events", max_attempts: 10

  @impl Oban.Worker
  def perform(arg1, _job) do
    IO.inspect(arg1)
  end
end

Enqueuing Jobs

We can now easily enqueue jobs to Oban. The adapter will handle a variety of argument formats.

# Please note that zero-arg jobs default to using %{}, as per Oban requirements.

# Push MyJob to your default queue with %{} arg.
{:ok, job} = Enqueuer.push(MyJob)

# Push MyJob to your default queue  with %{} arg.
{:ok, job} = Enqueuer.push({MyJob})

# Push MyJob to your default queue with %{"foo" => "bar"} arg.
{:ok, job} = Enqueuer.push({MyJob, %{"foo" => "bar"}})

# Push MyJob to "default" queue with %{} arg.
{:ok, job} = Enqueuer.push({MyJob, []})

# Push MyJob to "default" queue with %{"foo" => "bar"} arg.
{:ok, job} = Enqueuer.push({MyJob, [%{"foo" => "bar"}]})

# Push MyJob to "foo" queue with %{"foo" => "bar"} arg
{:ok, job} = Enqueuer.push({MyJob, %{"foo" => "bar"}}, [queue: "foo"])

# Schedule MyJob to your default queue with %{"foo" => "bar"} arg in 10 seconds
{:ok, job} = Enqueuer.push({MyJob, %{"foo" => "bar"}}, [delay: 10_000])

# Schedule MyJob to your default queue with %{"foo" => "bar"} arg at a specific time
date = DateTime.utc_now()
{:ok, job} = Enqueuer.push({MyJob, %{"foo" => "bar"}}, [delay: date])

Testing

Optionally, we can also have our tests use the GenQueue.Adapters.MockJob adapter.

config :my_app, Enqueuer, [
  adapter: GenQueue.Adapters.MockJob
]

This mock adapter uses the standard GenQueue.Test helpers to send the job payload back to the current processes mailbox (or another named process) instead of actually enqueuing the job to rabbitmq.

defmodule MyJobTest do
  use ExUnit.Case, async: true

  import GenQueue.Test

  setup do
    setup_test_queue(Enqueuer)
  end

  test "my enqueuer works" do
    {:ok, _} = Enqueuer.push(Job)
    assert_receive(%GenQueue.Job{module: Job, args: []})
  end
end

If your jobs are being enqueued outside of the current process, we can use named processes to recieve the job. This wont be async safe.

import GenQueue.Test

setup do
  setup_global_test_queue(Enqueuer, :my_process_name)
end

About

GenQueue Oban adapter for Elixir

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published