From a207ecde1b3c893fda92bee9a853500e499e2466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Fri, 31 May 2024 10:46:23 +0200 Subject: [PATCH] V3 du lock du website : Locked by (#1962) * locked_by_job_id * fix --- app/jobs/communication/website/base_job.rb | 4 ++-- app/models/communication/website/with_lock.rb | 18 +++++++++++++----- ..._add_locked_by_to_communication_websites.rb | 5 +++++ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20240531082129_add_locked_by_to_communication_websites.rb diff --git a/app/jobs/communication/website/base_job.rb b/app/jobs/communication/website/base_job.rb index 23eaa9179..3222a7240 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 f9d1912c0..ec40fa218 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 000000000..db4a22151 --- /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 -- GitLab