[error] GenServer {Oban.Registry, {Oban, {:plugin, Oban.Plugins.Stager}}}

Hello.

I cannot run mix test due to this error.

18:22:11.758 [error] GenServer {Oban.Registry, {Oban, {:plugin, Oban.Plugins.Stager}}} terminating
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.1432.0>.

When using ownership, you must manage connections in one
of the four ways:

* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
* By using :caller option with allowed process

The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.

The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.

The fourth option requires [caller: pid] to be used when
checking out a connection from the pool. The caller process
should already be allowed on a connection.

If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.

    (db_connection 2.4.0) lib/db_connection.ex:883: DBConnection.transaction/3
    (oban 2.7.2) lib/oban/plugins/stager.ex:83: anonymous fn/2 in Oban.Plugins.Stager.handle_info/2
    (telemetry 0.4.3) /Users/useeer/Documents/github/xxx/deps/telemetry/src/telemetry.erl:272: :telemetry.span/3
    (oban 2.7.2) lib/oban/plugins/stager.ex:82: Oban.Plugins.Stager.handle_info/2
    (stdlib 3.15.1) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.15.1) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: :stage

I added oban in the project, and the error occurs with oban.

config.exs

config :proj, Oban,
  repo: Proj.Repo,
  plugins: [
    Oban.Plugins.Pruner,
    {Oban.Plugins.Cron,
      crontab: [
        # {"work", ProjWeb._Worker}
      ]}
  ],
  queues: [default: 10, event: 50]

application.ex

    children = [
      ...
      {Oban, oban_config()}
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Proj.Supervisor]
    Supervisor.start_link(children, opts)

I don’t know where to check to solve the error.

And I have added this script in test.exs

config :proj, Oban, queues: false, plugins: false

The error you’re getting is definitely because plugins are running during tests.

It looks like you found the queues: false, plugins: false config, which is the proper fix. Maybe double check that everything is saved and that there aren’t any typos?

3 Likes

Also check (if and how) you’re using the standard DataCase, if you’re not using any other use that might try to setup the ecto sandbox, async tags that can conflict, and if you’re using any setup_all that might require explicit checkouts - from the top of my head.

2 Likes

Thank you for answering me!

Thank you, I have changed mode of the sandbox. then my tests work!

21:41:34.246 [error] GenServer {Oban.Registry, {Oban, {:plugin, Oban.Plugins.Pruner}}} terminating
** (DBConnection.ConnectionError) could not checkout the connection owned by #PID<0.1174.0>. When using the sandbox, connections are shared, so this may imply another process is using a connection. Reason: connection not available and request was dropped from queue after 104ms. You can configure how long requests wait in the queue using :queue_target and :queue_interval. See DBConnection.start_link/2 for more information
    (db_connection 2.4.0) lib/db_connection.ex:883: DBConnection.transaction/3
    (oban 2.7.2) lib/oban/plugins/pruner.ex:90: anonymous fn/2 in Oban.Plugins.Pruner.handle_info/2
    (telemetry 0.4.3) /Users/papillon/Documents/GitHub/Milk_DBServer/milk/deps/telemetry/src/telemetry.erl:272: :telemetry.span/3
    (oban 2.7.2) lib/oban/plugins/pruner.ex:89: Oban.Plugins.Pruner.handle_info/2
    (stdlib 3.15.1) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.15.1) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: :prune

Although the tests work, this error still appears in the terminal. do you have any ideas of fixing it?

There shouldn’t be any errors. Try putting this in one of your tests (any test):

IO.inspect(Oban.config())

You should see plugins: [] and queues: [] in there. If not, then your test config isn’t loading.

1 Like

OK, I’ll check it out!

I am having the same problem, just realized after two or three hours of head scratching. I think there are two approaches, but I don’t have the Elixir skills to do the first one:

  1. In the test environment, how do you checkout an Ecto connection NOT in Sandbox mode?

or

  1. Is there someway to just manually call Oban.Notifier after an insert to stimulate the producer to start executing available jobs?

I can’t find concrete examples of either one.

I was able to get things to work by adding the Oban.Plugins.Repeater plugin in the test Oban config. That was the only plugin I added to the config.

The way I recommend running Oban for tests is to have queues and plugins disabled entirely. When you need to check that something is enqueued you use the Testing helpers, and when you need to execute jobs you use drain_queue.

The goal is to keep async work predictable, and to avoid cross-process connection checkouts/sandbox issues.

In this case that means you would remove the repeater plugin and drain from within your test process.

1 Like

Hi, I have the same problem when running my tests just after installing Oban web+pro:

[error] GenServer {Oban.Registry, {Oban, {:plugin, Oban.Plugins.Stager}}} terminating
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.535.0>.

When using ownership, you must manage connections in one
of the four ways:

* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
* By using :caller option with allowed process

When I open a console in test environment, it still has the Oban config from config.exs instead of the config from test.exs:

MIX_ENV=test iex -S mix
Oban.config()
%Oban.Config{
  circuit_backoff: 30000,
  dispatch_cooldown: 5,
  engine: Oban.Pro.Queue.SmartEngine,
  get_dynamic_repo: nil,
  log: false, 
  name: Oban,
  node: "Hectors-MBP-2",
  notifier: Oban.PostgresNotifier,
  plugins: [Oban.Pro.Plugins.Lifeline, Oban.Web.Plugins.Stats,
   Oban.Plugins.Gossip, Oban.Pro.Plugins.DynamicPruner, Oban.Plugins.Stager],
  prefix: "public",
  queues: [
    default: [limit: 5],
    mailers: [limit: 5],
    events: [limit: 5],
    notifications: [limit: 5]
  ],
  repo: Wikir.Repo,
  shutdown_grace_period: 15000
}

However, test.exs seems to be loaded as MyApp.Repo.config() returns my test database.

In test.exs I have:

config :wikir, Oban, queues: false, plugins: false

And in config.exs I have:

config :wikir, Oban,
  repo: Wikir.Repo,
  engine: Oban.Pro.Queue.SmartEngine,
  plugins: [
    Oban.Pro.Plugins.DynamicPruner,
    Oban.Plugins.Gossip,
    Oban.Web.Plugins.Stats,
    Oban.Pro.Plugins.Lifeline],
  queues: [default: 5, mailers: 5, events: 5, notifications: 5],
  plugins: [{Oban.Pro.Plugins.DynamicPruner, mode: {:max_len, 50_000}}]

Any idea? Thanks!

Your config has plugins listed twice. Keyword lists (like config) allow that, but it breaks merging and therefore the Oban config.

Combine the two plugin lists and you’re golden :slightly_smiling_face:

Makes sense, thank you @sorentwo. However tests are still failing and Oban.config() in test env still returns all queues and plugins:

MIX_ENV=test iex -S mix
iex(2)> Oban.config()      
%Oban.Config{
  circuit_backoff: 30000,
  dispatch_cooldown: 5,
  engine: Oban.Pro.Queue.SmartEngine,
  get_dynamic_repo: nil,
  log: false, 
  name: Oban,
  node: "Hectors-MBP-2",
  notifier: Oban.PostgresNotifier,
  plugins: [
    {Oban.Pro.Plugins.DynamicPruner, [mode: {:max_len, 50000}]},
    Oban.Pro.Plugins.Lifeline,
    Oban.Web.Plugins.Stats,
    Oban.Plugins.Gossip,
    Oban.Plugins.Stager
  ],
  prefix: "public",
  queues: [
    default: [limit: 5],
    mailers: [limit: 5],
    events: [limit: 5],
    notifications: [limit: 5]
  ],
  repo: Wikir.Repo,
  shutdown_grace_period: 15000
}

Current config.exs:

config :wikir, Oban,
  repo: Wikir.Repo,
  engine: Oban.Pro.Queue.SmartEngine,
  plugins: [
    Oban.Pro.Plugins.DynamicPruner,
    Oban.Plugins.Gossip,
    Oban.Web.Plugins.Stats,
    Oban.Pro.Plugins.Lifeline,
    {Oban.Pro.Plugins.DynamicPruner, mode: {:max_len, 50_000}}],
  queues: [default: 5, mailers: 5, events: 5, notifications: 5]

Can you confirm that the test config was applied?

Application.get_env(:wikir, Oban)

That should have queues: false and plugins: false.

Can you also confirm that you’re using that config in your application’s supervision tree?

It isn’t being applied:

MIX_ENV=test iex -S mix
iex(5)> Application.get_env(:wikir, Oban)
[
  repo: Wikir.Repo,
  engine: Oban.Pro.Queue.SmartEngine,
  plugins: [
    Oban.Pro.Plugins.DynamicPruner,
    Oban.Plugins.Gossip,
    Oban.Web.Plugins.Stats,
    Oban.Pro.Plugins.Lifeline,
    {Oban.Pro.Plugins.DynamicPruner, [mode: {:max_len, 50000}]}
  ],
  queues: [default: 5, mailers: 5, events: 5, notifications: 5]
]

application.ex:

defmodule Wikir.Application do
  @moduledoc false

  use Application

  def start(_type, _args) do
    children = [
      Wikir.Repo,
      Wikir.LinkerServer,
      WikirWeb.Telemetry,
      {Phoenix.PubSub, name: Wikir.PubSub},
      WikirWeb.Endpoint,
      {Oban, oban_config()}
    ]

    opts = [strategy: :one_for_one, name: Wikir.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    WikirWeb.Endpoint.config_change(changed, removed)
    :ok
  end

  defp oban_config do
    Application.fetch_env!(:wikir, Oban)
  end
end

And test.exs:

use Mix.Config
config :wikir, Wikir.Repo,
  ...

config :wikir, Oban, queues: false, plugins: false
...

Any idea about what am I doing wrong? Thank you!

Overriding and merging application config is handled by Elixir/Erlang, that isn’t something that Oban is doing. Provided you have import_config "#{Mix.env()}.exs" at the end of your config.exs, everything should work as expected.

To test more you can put something like this in test.exs:

config :wikir, Random.Thing, does_this_work?: true

Then check with Application.get_env(:wikir, Random.Thing).

3 Likes

I had import_config above Oban’s config. What a silly mistake.
Many thanks @sorentwo and sorry for the inconvenience!

5 Likes