oban-bg / oban

💎 Robust job processing in Elixir, backed by modern PostgreSQL and SQLite3
https://oban.pro
Apache License 2.0
3.37k stars 314 forks source link

Recommended approach to enqueue a job with a guaranteed minimum delay #1080

Closed TheOneric closed 6 months ago

TheOneric commented 6 months ago

There appear to be two mechanisms for delaying job execution. I do not care about the exact execution time, only that at least a certain amount of time elapses before job execution is attempted. (the specific scenario is granting a grace period before resources are actually deleted to allow undoing a mishap, since resources can be referenced by multiple parties the grace period for attempting clean up should have a minimum delay from the latest related request)

snooze’s documentation speaks of delaying by "at least" the specified time exactly matching what i want. But is slightly less intuitive to use and requires checking the current attempt countand snooze on the first run. I’m not sure how to best combine this with replace.

The former would be more convenient to use, but it’s documentation talks about scheduling “down to the second”, i.e. it will try to exactly match the specified time. I’m wondering if this has any performance implications and how this will interact with concurrent-job limits of a queue and priorities of other jobs?

Alternatively, if Oban’s builtin delay functions are a bad fit here, i could keep track of all resource for which a cleanup was requested plus when the last request was made cleanup requests and regularly scan over them, enqueueing jobs for all eligible items.

Is there any recommended "best practice" approach to get the described delay behaviour?

sorentwo commented 6 months ago

The correct approach is to use scheduled_at/scheduled_in to set a point on, or after, you want a job to run.

Oban's scheduling guarantees that a job will be made available for execution at the specified time, not that it will execute at that exact moment. The snooze return uses the same mechanism, it marks the job as scheduled and then it can run after some amount of time.