Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay an existing job or schedule a new job #645

Merged
merged 1 commit into from
Jan 31, 2022

Conversation

cbisnett
Copy link
Contributor

Add functionality to find previously delayed jobs and update their timestamp or queue a new job if no previously delayed jobs match. This is similar to the find_or_create_by functionality of ActiveRecord.

The current implementation doesn't care about the timestamps of the existing jobs and will update all matching jobs to the specified timestamp. This means that some jobs may be delayed further into the future and others may be executed sooner. Example:

     Job1                  Job2
------^----------*----------^
            New Timestamp

Background
Several times I've found myself needing a solution for a batching up some background work. One of the most common patterns is notifying users when some event happens. The most naive solution is to send an email when an event is created. In some situations this is fine, except when several events happen within a short period of time. Users will quickly get annoyed that you're filling their inbox with notification emails. So the obvious step is to batch up the emails and only send a few notification emails containing multiple events.

I've implemented this previously by creating a scheduled job that runs every X minutes and finds all the notifications that haven't been sent, marks them as sent, and sends the notification email. This works OK except it's hard to control the trade-off between sending the notification in a timely manner and not sending too many emails. For example, if the scheduled job is set to run every 10 minutes and an event is created within the first minute, the notification won't be sent for 9 minutes or more. This isn't ideal because the notification took quite a while to be sent. On the other hand if 50 events are created within the 10 minute window then we've saved the user 49 emails.

With this functionality it's really easy to implement a better solution. When an event is created it will either create a new background job or will delay an existing scheduled job. So we can implement a system that will send a notification email within X minutes of the last event. If a bunch of events are created in quick succession the background job's delayed timer will keep getting reset but will still run within X minutes of the last event. This way we can decrease the window and send the notification emails with less of a delay but still avoid sending too many emails when several events trigger in quick succession.

Copy link
Contributor

@iloveitaly iloveitaly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cbisnett Thanks for the detailed description! I'll take a deeper look a bit later, but it looks good to me.

Couple things before merging:

  • Could you rebase on master so CI runs?
  • Could you add a changelog entry?

Would love to get this merged into master!

@cbisnett
Copy link
Contributor Author

Let me see if I can rebase this on the latest master.

@cbisnett cbisnett force-pushed the delay_or_enqueue_at branch from cdca208 to 236673f Compare November 30, 2021 00:14
Add a helper function that will remove any matching delayed jobs and
reschedule them with the specified delay or schedule a new job if there
are no matching delayed jobs.
@cbisnett cbisnett force-pushed the delay_or_enqueue_at branch from 236673f to fc9804f Compare November 30, 2021 00:20
@cbisnett
Copy link
Contributor Author

@iloveitaly Rebased and added a changelog entry. Let me know if there is anything to be done to get this merged.

@iloveitaly iloveitaly merged commit f8b6898 into resque:master Jan 31, 2022
@iloveitaly
Copy link
Contributor

Thank you! This is a neat feature.

@matthewhively
Copy link

Any ETA when this will be tagged for release?

@cbisnett cbisnett deleted the delay_or_enqueue_at branch February 24, 2022 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants