Debouncing is a common method to postpone a function/job from executing until after certain time has passed.
Use-case: A conversation with active chatting from multiple users, they should not receive an email notification for each message typed. But more than likely after a few minutes of silence, if the messages are unread, the user should see a notification.
Delayed_Job
Has no solution, has related issues: https://github.com/collectiveidea/delayed_job/issues/72
Sidekiq
Doing yourself is not so bad.
class AdminJob
def self.debounce(job, args={})
handler = YAML.dump(job)
count = Delayed::Job.where(handler: handler).where('locked_at IS NULL').delete_all
Rails.logger.info("deleted: #{count} jobs")
Delayed::Job.enqueue(job, args)
end
end
Instead of writing:
Delayed::Job.enqueue(YourJobName.new(account_id), {run_at: 10.minutes.from_now})
You now write:
AdminJob.debounce(YourJobName.new(account_id), {run_at: 10.minutes.from_now})
Delayed job serializes your job params in YAML
and then saves it to the database as handler
. So if you call AdminJob.debounce(...)
10 times in a row, it will delete before each.
Make sure to give yourself time (5.minutes, etc) to give users to keep taking actions. If you run your job after 1 second, its likely they'll keep taking actions and trigger again.
Yes i'm answering my own question 3 years later...