diff --git a/app/jobs/communication/website/base_job.rb b/app/jobs/communication/website/base_job.rb index 23eaa91794fdd360165fe129e49d86e2cf869357..3222a7240ffb1a37865f7325e37bb2440e6add52 100644 --- a/app/jobs/communication/website/base_job.rb +++ b/app/jobs/communication/website/base_job.rb @@ -20,9 +20,9 @@ class Communication::Website::BaseJob < ApplicationJob # Website might be deleted in between return unless website.present? # Raise if website is locked to retry later - raise Communication::Website::LockError.new("Interrupted because of website lock.") if website.locked_for_background_jobs? + raise Communication::Website::LockError.new("Interrupted because of website lock.") if website.locked_for_background_jobs?(job_id) # We lock the website to prevent race conditions - website.lock_for_background_jobs! + website.lock_for_background_jobs!(job_id) begin # We execute the job execute diff --git a/app/models/communication/website/with_lock.rb b/app/models/communication/website/with_lock.rb index f9d1912c04cc2025995a6697605d8fda37e6c0c1..ec40fa218da72bccc774d9a25cd36f3b75b48ccc 100644 --- a/app/models/communication/website/with_lock.rb +++ b/app/models/communication/website/with_lock.rb @@ -6,16 +6,24 @@ module Communication::Website::WithLock LOCK_MAX_DURATION = 2.hours end - def locked_for_background_jobs? + def locked_for_background_jobs?(executing_job_id) reload - locked_at.present? + locked_at.present? && # Not locked if locked_at is nil + locked_by_job_id != executing_job_id && # If the website was locked by the same job, we can continue + GoodJob::Job.running.find_by(id: locked_by_job_id).present? # Check if the locking job is still running (to handle SIGKILL and hard shutdowns) end - def lock_for_background_jobs! - update_column :locked_at, Time.zone.now + def lock_for_background_jobs!(job_id) + update_columns( + locked_at: Time.zone.now, + locked_by_job_id: job_id + ) end def unlock_for_background_jobs! - update_column :locked_at, nil + update_columns( + locked_at: nil, + locked_by_job_id: nil + ) end end diff --git a/db/migrate/20240531082129_add_locked_by_to_communication_websites.rb b/db/migrate/20240531082129_add_locked_by_to_communication_websites.rb new file mode 100644 index 0000000000000000000000000000000000000000..db4a2215142be842e3aaf7900b612479245af3d0 --- /dev/null +++ b/db/migrate/20240531082129_add_locked_by_to_communication_websites.rb @@ -0,0 +1,5 @@ +class AddLockedByToCommunicationWebsites < ActiveRecord::Migration[7.1] + def change + add_column :communication_websites, :locked_by_job_id, :uuid + end +end