I have an Oban Workflow
that I want to limit so that only 1 Workflow
will run for a user at a time, but not block for other users.
From the config it looks like I can do this per worker, but my workflow could have concurrent workers.
I don’t know if there is a way to do this with Oban config
help!
Any ideas?
Depending in the users amount, I would use a GenServer per user, saving in the state the jobs queue and a tick function wich take the first in the list, execute and update the state…
If you want to persist the state in case of crashes and you are not using a cluster, you can save the state in ETS… and load it again in the init callback.
If you are using a cluster, you can use Horde and recover the state with :continue flag.
I’m not sure if I would use Oban for this case…
1 Like
it’s an Oban Workflow that I am trying to run uniquely
Yes! Indeed, there is. With Pro v1.6 you can set a global partition by workflow_name
or some other unique attribute of that users workflow. (That’s really up to you). It’s more about concurrency and not uniqueness.
config :my_app, Oban,
queues: [
queue_name: [limit: 20, global_limit: [allowed: 1, partition: [meta: :workflow_name]]]
]
In this case, each node can run up to 20 jobs but only 1 of that particular workflow. It relies on you setting a distinct workflow name for each user.
Workflow.new(workflow_name: "some-workflow-#{user_id}")
4 Likes
Nice! Is 1.6 ready for prod use yet?
Just reading 1.6 docs now.
Can I use the new context
in the partition?
e.g.
global_limit: [allowed: 1, partition: [meta: :workflow_name, context: :user_id]]
*edit: looks like no. workflow_name will work, though. thanks
Worker name or workflow name? 
We run it in production. It’s in rc for a while, at least a month. Totally up to you.
1 Like