From 2161cb8f90b8596ade9fe8f5d1f955a95a86b9f1 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Thu, 7 Sep 2023 17:30:11 +0200
Subject: [PATCH] gem

---
 Gemfile                                       |  1 +
 Gemfile.lock                                  |  3 +
 config/initializers/delayed_jobs.rb           | 12 ---
 ...907152751_add_signature_to_delayed_job.rb} |  6 +-
 db/schema.rb                                  |  2 +-
 lib/delayed_duplicate_prevention_plugin.rb    | 73 -------------------
 6 files changed, 9 insertions(+), 88 deletions(-)
 rename db/migrate/{20230907085800_add_key_to_delayed_jobs.rb => 20230907152751_add_signature_to_delayed_job.rb} (53%)
 delete mode 100644 lib/delayed_duplicate_prevention_plugin.rb

diff --git a/Gemfile b/Gemfile
index 53b050864..bbcc91023 100644
--- a/Gemfile
+++ b/Gemfile
@@ -22,6 +22,7 @@ gem "country_select"
 gem "csl-styles", "~> 2.0"
 gem "curation"#, path: "../../arnaudlevy/curation"
 gem "delayed_job_active_record"
+gem "delayed_job_prevent_duplicate"
 gem "delayed_job_web"
 gem "devise"
 gem "devise-i18n"
diff --git a/Gemfile.lock b/Gemfile.lock
index ec027c15b..6657633f9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -182,6 +182,8 @@ GEM
     delayed_job_active_record (4.1.7)
       activerecord (>= 3.0, < 8.0)
       delayed_job (>= 3.0, < 5)
+    delayed_job_prevent_duplicate (0.1.0)
+      delayed_job (>= 3.0, < 5)
     delayed_job_web (1.4.4)
       activerecord (> 3.0.0)
       delayed_job (> 2.0.3)
@@ -599,6 +601,7 @@ DEPENDENCIES
   csl-styles (~> 2.0)
   curation
   delayed_job_active_record
+  delayed_job_prevent_duplicate
   delayed_job_web
   devise
   devise-i18n
diff --git a/config/initializers/delayed_jobs.rb b/config/initializers/delayed_jobs.rb
index 9fdb383d0..1ed52dd7c 100644
--- a/config/initializers/delayed_jobs.rb
+++ b/config/initializers/delayed_jobs.rb
@@ -3,15 +3,3 @@ Delayed::Worker.queue_attributes = {
   low_priority: { priority: 10 },
   imports: { priority: 5 }
 }
-
-# Avoid duplicates
-
-# https://groups.google.com/g/delayed_job/c/gZ9bFCdZrsk#2a05c39a192e630c
-# https://github.com/collectiveidea/delayed_job/blob/master/lib/delayed/backend/base.rb
-# https://github.com/ignatiusreza/activejob-trackable
-
-# based on https://gist.github.com/synth/fba7baeffd083a931184
-require 'delayed_duplicate_prevention_plugin'
-
-Delayed::Backend::ActiveRecord::Job.send(:include, DelayedDuplicatePreventionPlugin::SignatureConcern)
-Delayed::Worker.plugins << DelayedDuplicatePreventionPlugin
\ No newline at end of file
diff --git a/db/migrate/20230907085800_add_key_to_delayed_jobs.rb b/db/migrate/20230907152751_add_signature_to_delayed_job.rb
similarity index 53%
rename from db/migrate/20230907085800_add_key_to_delayed_jobs.rb
rename to db/migrate/20230907152751_add_signature_to_delayed_job.rb
index b500645e2..84df91178 100644
--- a/db/migrate/20230907085800_add_key_to_delayed_jobs.rb
+++ b/db/migrate/20230907152751_add_signature_to_delayed_job.rb
@@ -1,6 +1,8 @@
-class AddKeyToDelayedJobs < ActiveRecord::Migration[7.0]
+# frozen_string_literal: true
+
+class AddSignatureToDelayedJob < ActiveRecord::Migration[7.0]
   def change
     add_column :delayed_jobs, :signature, :string
     add_column :delayed_jobs, :args, :text
   end
-end
+end
\ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
index a2aba470b..25f9caafe 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2023_09_07_085800) do
+ActiveRecord::Schema[7.0].define(version: 2023_09_07_152751) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
diff --git a/lib/delayed_duplicate_prevention_plugin.rb b/lib/delayed_duplicate_prevention_plugin.rb
deleted file mode 100644
index 43bf45d0b..000000000
--- a/lib/delayed_duplicate_prevention_plugin.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require 'delayed_job'
-class DelayedDuplicatePreventionPlugin < Delayed::Plugin
- 
-  module SignatureConcern
-    extend ActiveSupport::Concern
-
-    included do
-      before_validation :add_signature
-      validate :prevent_duplicate
-    end
-
-    private
-
-    def add_signature
-      self.signature = generate_signature
-      self.args = self.payload_object.args
-    end
-
-    def generate_signature
-      pobj = payload_object
-      if pobj.object.respond_to?(:id) and pobj.object.id.present?
-        sig = "#{pobj.object.class}"
-        sig += ":#{pobj.object.id}" 
-      else
-        sig = "#{pobj.object}"
-      end
-      
-      sig += "##{pobj.method_name}"
-      return sig
-    end    
-
-    def prevent_duplicate
-      if DuplicateChecker.duplicate?(self)
-        Rails.logger.warn "Found duplicate job(#{self.signature}), ignoring..."
-        errors.add(:base, "This is a duplicate") 
-      end
-    end
-  end
-
-  class DuplicateChecker
-    attr_reader :job
-
-    def self.duplicate?(job)
-      new(job).duplicate?
-    end
-
-    def initialize(job)
-      @job = job
-    end
-
-    def duplicate?
-      possible_dupes.any? { |possible_dupe| args_match?(possible_dupe, job) }
-    end
-
-    private
-
-    def possible_dupes
-      possible_dupes = Delayed::Job.where(attempts: 0, locked_at: nil)  # Only jobs not started, otherwise it would never compute a real change if the job is currently running
-                                   .where(signature: job.signature)     # Same signature
-      possible_dupes = possible_dupes.where.not(id: job.id) if job.id.present?
-      possible_dupes
-    end
-
-    def args_match?(job1, job2)
-      # TODO: make this logic robust
-      normalize_args(job1.args) == normalize_args(job2.args)
-    end
-
-    def normalize_args(args)
-      args.kind_of?(String) ? YAML.load(args) : args
-    end
-  end
-end
\ No newline at end of file
-- 
GitLab