I’m using the new Oban Pro 1.5 workflow API. Currently, the workflow has three jobs. Job A runs first. Jobs B and C are dependent on A and can run concurrently.
Jobs A and B depend on a 3rd party API. We have recently learned that we need to add a couple of minute delay between jobs A and B. Job C can continue to run immediately after A completes. Is there a way to do this simply through Workflow configuration? Based on the the docs at Oban.Pro.Workflow — Oban Pro v1.5.0-rc.6, my current understanding is no.
If this is not something that workflows currently support, we have some options.
Stop using workflows in this case. We don’t strictly need them here. We can manually enqueue jobs after each step.
Add a no-op job into the workflow between A and B that just sleeps for a couple of minutes.
This is best done if you use ETS and store the last timestamp when the 3rd party API was hit, and when Job B starts it should sleep until the requisite grace period has passed. No need for dummy jobs inbetween. But…
I’d agree if you only have jobs A, B and C, plus in this case you can just set scheduled_at directly and you don’t have to use :timer.sleep anywhere which is IMO much better design.
Thanks for the input on this. Of course, real world usage is more complicated than my simplified example, but this feedback put me down a good path.
Our workflows can get somewhat complicated and we want to define as much of them as possible up front to centralize the domain knowledge about how the business process operates. That means I want to avoid adding jobs dynamically as much as possible, which makes scheduled_at a tougher sell though.
We also have the issue that these jobs can be used in a couple of different workflows with slightly different contexts, so we don’t want to couple them together more than necessary.
However, we can use snoozing to get a similar result. Job B takes an argument telling it how long it snooze. When the job runs, we can check if it’s snoozed before (See Oban.Pro.Engines.Smart — Oban Pro v1.5.0-rc.6). If it hasn’t snoozed yet, then we snooze it for the passed in number of seconds.
The end result is that job A completes first. This unblocks job B. B runs and immediately snoozes for the configured amount of time.