Sha256: 09668ca180565c609c5b58f4d9c54c8f19b257b0c5a0a072f7b7f6643d39ad1f

Contents?: true

Size: 1.92 KB

Versions: 1

Compression:

Stored size: 1.92 KB

Contents

require_relative "duplicate_checker"

module DelayedJobPreventDuplicate
  module SignatureConcern
    extend ActiveSupport::Concern

    included do
      before_validation :generate_signature
      validate :prevent_duplicate
    end

    private

    def generate_signature
      self.signature = signature_from_denormalized_data || random_signature
    end

    def signature_from_denormalized_data
      begin
        Digest::MD5.hexdigest(denormalized_data.to_json)
      rescue
        puts "DelayedJobPreventDuplicate could not generate the signature correctly."
        nil
      end
    end

    def random_signature
      SecureRandom.uuid
    end

    def denormalized_data
      @denormalize_data ||= begin
        if payload_object.is_a?(Delayed::PerformableMethod)
          denormalized_data_for_performable_method
        else
          denormalized_data_for_job_wrapper
        end
      end
    end

    # Methods tagged with handle_asynchronously
    def denormalized_data_for_performable_method
      {
        object: payload_object.object.to_global_id.to_s,
        method_name: payload_object.method_name,
        args: stringify_arguments(payload_object.args)
      }
    end

    # Regular Job
    def denormalized_data_for_job_wrapper
      {
        job_class: payload_object.job_data["job_class"],
        args: stringify_arguments(payload_object.job_data["arguments"])
      }
    end

    def stringify_arguments(arguments)
      serialize_arguments(arguments).join('|')
    end

    def serialize_arguments(arguments)
      arguments.map { |argument|
        argument.is_a?(ActiveRecord::Base)  ? argument.to_global_id.to_s
                                            : argument.to_json
      }
    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
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
delayed_job_prevent_duplicate-0.2.0 lib/delayed_job_prevent_duplicate/signature_concern.rb