Last active
May 31, 2024 20:18
-
-
Save eparreno/9f82d6012e6585a9346b to your computer and use it in GitHub Desktop.
How to delete Sidekiq jobs in a Rails app using ActiveJobs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Sidekiq jobs can be enqueued or scheduled. Enqueued means that they are gonna be picked up as soon as possible, | |
| scheduled jobs will be enqueued at some specific time. | |
| ## job_id and jid | |
| When using ActiveJobs, Rails will return a `job_id` after sending the job to ActiveJobs | |
| ``` | |
| job = UserMailer.send_invite(params).deliver_later | |
| job.job_id => "9fb7b1f3-0159-49dd-b886-dfb8df991cd6" | |
| ``` | |
| Keep in mind that this is not the id Sidekiq uses to reference jobs internally. To get the Sidekiq `jid` | |
| ``` | |
| # enqueued jobs | |
| job = UserMailer.send_invite(params).deliver_later | |
| Sidekiq::Queue.new("mailers").find { |job_id| job.job_id }.item["jid"] | |
| # scheduled jobs | |
| job = UserMailer.send_invite(params).deliver_later(wait: 1.hour) | |
| Sidekiq::ScheduledSet.new.find { |job_id| job.job_id }.item["jid"] | |
| ``` | |
| ## Enqueued jobs | |
| Here's a typical example in a Rails app | |
| ``` | |
| job = UserMailer.send_invite(params).deliver_later | |
| ``` | |
| That jobs will go straight to the queue and will get processed as soon as possible. | |
| Keep in mind that Sidekiq is fast as hell so if there are enough resources that job will be executed with virtually no delay, so it's | |
| almost impossible to delete a job from the queue unless Sidekiq is busy processing other jobs, that will give you some time to | |
| delete the job. | |
| ``` | |
| queue = Sidekiq::Queue.new("mailer") | |
| queue.each do |job| | |
| # using jid | |
| job.delete if job.jid == 'sidekiq_job_id' | |
| # using job_id | |
| job.delete if job.job_id == 'rails_job_id' | |
| end | |
| ``` | |
| ## Scheduled jobs | |
| In that case you'll have a bit more time to delete the job ;) | |
| ``` | |
| job = UserMailer.send_invite(params).deliver_later(wait: 1.hour) | |
| ``` | |
| ``` | |
| ss = Sidekiq::ScheduledSet.new | |
| ss.select { |job_id| job.job_id }.each(&:delete) | |
| ``` | |
| or using the `jid` | |
| ``` | |
| jid = Sidekiq::ScheduledSet.new.find { |job_id| job.job_id }.item["jid"] | |
| Sidekiq::ScheduledSet.new.find_job(jid).delete | |
| ``` | |
| or matching jobs by class instead of by ID | |
| ``` | |
| ss = Sidekiq::ScheduledSet.new | |
| jobs = ss.select {|job| job.klass == 'SomeWorker' } | |
| jobs.each(&:delete) | |
| ``` |
I'm a little worried that adding a delay to some jobs will be unacceptable (product-wise).
In particular, imagine the "guest creates new trip" flow on TripGun:
- I create a trip, add legs, input my email and click "Go!"
- The mobile app notifies me that a confirmation email will arrive shortly
- Without the delay -- within seconds (hopefully the time it took me to read the text on the previous step) I see a push notification that I just received an email, tap to view and tap to confirm
- With the delay -- I don't see any notification popping up so I either head to my mail client and refresh or just lock my phone and put it back to my pocket
In particular, I would hate our first time users to put their phone back in their pocket because it might take them some time (hours, days) to check their email again. Since this is a product thing I would expect others have more to-the-point feedback to give.
I totally agree. I'm not saying we should delay all the jobs to have time to delete them, just pointing out all the options available.
job = UserMailer.send_invite(params).deliver_later
job.job_id => "9fb7b1f3-0159-49dd-b886-dfb8df991cd6" ActiveJob id
job.provider_job_id => "5f4cbb0d87a46ec845b6ea92" Sidekiq id
I think Sidekiq::Queue.new("mailers").find { |entry| entry.args.first.fetch('job_id') == job.job_id } would be the right way to find a corresponding job.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sidekiq::Queue.new("mailers").find { |job_id| job.job_id }.item["jid"]looks like is should beSidekiq::Queue.new("mailers").find { |job_id| job_id == job.job_id }.item["jid"]