I'm using Oban for the ongoing tasks.
# .....
{Oban.Plugins.Cron,
crontab: [
{"* * * * *", MyApp.Workers.W1},
{"* * * * *", MyApp.Workers.W2},
]},
I now need to run W1
and W2
more frequently that every minute - around once in every 10...30 seconds. Since cron doesn't support higher frequency than 1/min, how would I get around this limitation? Preferably without hacks, unless absolutely necessary.
I don't consider switching from Oban to other library.
I don't believe Oban.Plugins.Cron
supports granularity finer than one minute, by glancing at the current code.
One way you could do this is by having a process (like a GenServer) in your application that uses Process.send_after/3
or :timer.send_interval/2
to periodically queue the Oban jobs you want. This is essentially what Oban.Plugins.Cron
is doing. You'll probably want to pay attention to making sure the jobs are unique (documentation).
Some very simplified code:
defmodule MyApp.Scheduler do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, :no_args)
end
@impl true
def init(:no_args) do
:timer.send_interval(:timer.seconds(30), {:schedule_job, MyApp.Workers.W1, 30})
:timer.send_interval(:timer.seconds(20), {:schedule_job, MyApp.Workers.W2, 20})
{:ok, :no_state}
end
@impl true
def handle_info({:schedule_job, worker, unique_seconds}, state) do
%{my: :params}
|> Oban.Job.new(worker: worker, unique: [period: unique_seconds])
|> Oban.insert!()
{:noreply, state}
end
end