I have an Elixir apps which does some harder jobs in the background. I am using Oban to run them asynchrously. For better availability I’d like to spawn a second server instance of my Elixir app (I am using fly.io) but without spawing another Oban app there.
Currently Oban is just part of the Standard Application Supervision Tree:
def start(_type, _args) do
children = [
# Start the Ecto repository
MyApp.Repo,
MyAppWeb.Telemetry,
{Phoenix.PubSub, name: MyApp.PubSub},
MyAppWeb.Endpoint,
{Oban, Application.fetch_env!(:my_app, Oban)}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
I guess it can. But I have like jobs which need a lot of processing power. So I don’t wanna let them run on my web facing machine which has less power.
I see, thank you. My problem is more that all of the machines have the same set of environment variables. So I need to figure out how to start it on the first machine only or have a different set of environment variables.
Sorry, didn’t mean to reply directly to you! Oban does a great job of this already, but if you want to run any old process as a singleton globally, Highlander is worth looking at.
I believe that guarantee is available in non-paid version. Though you’d need to upgrade to Pro to have more control across the whole cluster (see SmartEngine).
Just to understand that better. So with uniqueness you mean, the job is only executed once not multiple times when you have multiple nodes, right?
And Global Concurrency means that you can say, I want to run x jobs across all of my nodes. Without you could only set a concurrency limit per node and the global limit is basically: local_limit x number_of_nodes. Is that correct? Thank you!
One small note regarding Oban’s cron and how it interplays with uniqueness: the cron plugin inserts a single job which may be picked up by any node, just like any other job.