Oban Pro: DynamicCron doesn't support unique option

Hello!

I just started upgrading Oban from OSS version to Pro and found that the old config:

config :my_project, Oban,
  repo: MyProject.Repo,
  plugins: [
    Oban.Plugins.Pruner,
    {Oban.Plugins.Cron,
     crontab: [
       {
         "* * * * *", # runs every minute
         MyProject.Worker,
         max_attempts: 1,
         unique: [
           # Unique in every 15 minutes
           period: 60 * 15,
           states: [:available, :scheduled, :executing]
         ]
       }
     ]}
  ],
  queues: [...]

then converted to Pro version:

config :my_project, Oban,
  engine: Oban.Pro.Queue.SmartEngine,
  repo: MyProject.Repo,
  plugins: [
    Oban.Pro.Plugins.DynamicLifeline,
    Oban.Pro.Plugins.DynamicPruner,
    {Oban.Pro.Plugins.DynamicCron,
     crontab: [
       {
         "* * * * *", # runs every minute
         MyProject.Worker,
         max_attempts: 1,
         unique: [
           # Unique in every 15 minutes
           period: 60 * 15,
           states: [:available, :scheduled, :executing]
         ]
       }
     ]}
  ],
  queues: [...]

Produces the following error:

17:41:15.098 [module=gen_server ][error] GenServer {Oban.Registry, {Oban, {:plugin, Oban.Pro.Plugins.DynamicCron}}} terminating
** (stop) %ArgumentError{message: [opts: {"expected cron opts to be one of [:args, :max_attempts, :priority, :queue, :tags, :timezone]", []}]}
Last message: {:continue, :start}

Oban version: 2.12.1
Oban Pro version: 0.11.1

I compared code of DynamicCron between the latest Pro version which is 0.12.4 and version 0.11.1. The diff is empty which tells me it should work the same in the latest version.

Is this intended for Pro, so I can set job uniqueness period in OSS version but cannot do that in Pro?

Meanwhile I’m trying to set it as an option inside use Oban.Worker.

Yes, moving this unique option inside a Worker worked. I think it should be pointed in docs that unique cannot be used in the app config.

Sorry for the confusion!

There is a section in the docs that calls out which options are allowed:

The following call demonstrates updating every possible option:

{:ok, _} =
  DynamicCron.update(
    "cron-1",
    expression: "1 * * * *",
    max_attempts: 10,
    name: "special-cron",
    paused: false,
    priority: 0,
    queue: "dedicated",
    tags: ["client", "scheduled"],
    timezone: "Europe/Amsterdam",
    worker: Other.Worker,
  )

Setting unique overrides on Cron is usually a recipe for confusion, which is why it isn’t available as an option.

1 Like

I agree it is confusing to see unique setting inside the cron definition. At the same time the job may take longer than we expect (it interacts with external system) so we have to ensure it is not enqueuing when external system down/slowly responds.