How to create a task with Oban, does not work

Hi friends, I created a function and module based on Oban README, but it does not work I think.

defmodule MyApp.Business do
  use Oban.Worker, queue: :events

  @impl Oban.Worker
  def perform(%Oban.Job{args: %{"id" => id} = args}) do
    case args do
      %{"in_the" => "business"} ->
        IO.inspect("business")
      %{"vote_for" => vote} ->
        IO.inspect(vote)
      _ ->
        IO.inspect("model")
    end
    :ok
  end
end

After that

%{id: 98, vote_for: "none of the above"}
|> MyApp.Business.new(queue: :special, max_attempts: 5) #or |> MyApp.Business.new()
|> Oban.insert()

and it shows me this:

{:ok,
 %Oban.Job{
   __meta__: #Ecto.Schema.Metadata<:loaded, "public", "oban_jobs">,
   args: %{id: 98, vote_for: "none of the above"},
   attempt: 0,
   attempted_at: nil,
   attempted_by: nil,
   cancelled_at: nil,
   completed_at: nil,
   conf: nil,
   conflict?: false,
   discarded_at: nil,
   errors: [],
   id: 3,
   inserted_at: nil,
   max_attempts: 5,
   meta: %{},
   priority: 0,
   queue: "special",
   replace: nil,
   scheduled_at: nil,
   state: "available",
   tags: [],
   unique: nil,
   unsaved_error: nil,
   worker: "MyApp.Business"
 }}

It does not print anything

my config:

config :trackapp, Oban,
  repo: Trackapp.Repo,
  plugins: [Oban.Plugins.Pruner],
  queues: [default: 10]

psql (PostgreSQL) 14.3

Elixir 1.13.3 (compiled with Erlang/OTP 24)

Since Oban is for performing background tasks, even the one you defined is performed in the background. That means the argument of the IO.inspect function won’t be printed to your iex session (I assume you’re using iex to test this) but to a process it is happening in.

You have a few options I can think of here. Maybe someone can add another.

You can use a Logger instead of IO.inspect so that it will log the text to stdout.

Another simple thing you can do instead of IO.inspect is something like File.write("hello.txt", "world") and then checking the content of that file in your project root folder.

But the best and recommended way to be sure your jobs are working properly is testing.

1 Like

Even I tested to write a file like this: File.write("/Users/shahryar/Desktop/trackapp/hello.txt", "world") it does not work for me or with Logger

You have queue: :events in the worker definition. Then queue: "special" in the job returned from Oban.insert() and only default queue defined in your configuration. I guess it happened during your experiments, but make sure you specify a queue in the worker module that is also present in the Oban configuration.

1 Like

Yeah, you are right, I needed to add event and special in my config. Thank you.

I have another question: I saw in documents we can pause the jobs and resume them. I have a function in my project that does some stuff in a task and after is successful it sends a Pubsub.
So when it is doing something maybe users want to send another request which should be put in queue.

Now the queue should send the jobs one by one and check if the job is being done, if is there running task it should not run another task

I have no idea how to do it with Oban. It is for learning.

If I understand your requirements correctly, you just need to specify 1 as a number of concurrent jobs for that queue. That means if one job is running, others are waiting. See here.

1 Like

It seems that you should also check Unique Jobs section. So, it’s possible to specify constraints to prevent enqueueing duplicate jobs, like:

use Oban.Worker, unique: [states: [:available, :scheduled, :executing]]
1 Like

Is there a function to count running tasks and queued tasks with their status? Like available or scheduled? Or we should query to database?

I could not find in Oban — Oban v2.12.1 page