Class: Resque::UniqueByArity::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/resque/unique_by_arity/configuration.rb

Constant Summary collapse

VALID_ARITY_VALIDATION_LEVELS =
[ :warning, :error, :skip, nil, false ]
SKIPPED_ARITY_VALIDATION_LEVELS =
[ :skip, nil, false ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Configuration

Returns a new instance of Configuration.

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/resque/unique_by_arity/configuration.rb', line 17

def initialize(**options)
  @logger = options.key?(:logger) ? options[:logger] : Logger.new(STDOUT)
  @log_level = options.key?(:log_level) ? options[:log_level] : :debug
  @arity_for_uniqueness = options.key?(:arity_for_uniqueness) ? options[:arity_for_uniqueness] : 1
  @arity_validation = options.key?(:arity_validation) ? options[:arity_validation] : :warning
  raise ArgumentError, "UniqueByArity::Cop.new requires arity_validation values of #{arity_validation.inspect}, or a class inheriting from Exception, but the value is #{@arity_validation} (#{@arity_validation.class})" unless VALID_ARITY_VALIDATION_LEVELS.include?(@arity_validation) || !@arity_validation.respond_to?(:ancestors) || @arity_validation.ancestors.include?(Exception)
  @lock_after_execution_period = options.key?(:lock_after_execution_period) ? options[:lock_after_execution_period] : nil
  @runtime_lock_timeout = options.key?(:runtime_lock_timeout) ? options[:runtime_lock_timeout] : nil
  @unique_at_runtime = options.key?(:unique_at_runtime) ? options[:unique_at_runtime] : false
  @unique_in_queue = options.key?(:unique_in_queue) ? options[:unique_in_queue] : false
  @unique_across_queues = options.key?(:unique_across_queues) ? options[:unique_across_queues] : false
end

Instance Attribute Details

#arity_for_uniquenessObject

Returns the value of attribute arity_for_uniqueness.



9
10
11
# File 'lib/resque/unique_by_arity/configuration.rb', line 9

def arity_for_uniqueness
  @arity_for_uniqueness
end

#arity_validationObject

Returns the value of attribute arity_validation.



10
11
12
# File 'lib/resque/unique_by_arity/configuration.rb', line 10

def arity_validation
  @arity_validation
end

#base_klass_nameObject

Returns the value of attribute base_klass_name.



16
17
18
# File 'lib/resque/unique_by_arity/configuration.rb', line 16

def base_klass_name
  @base_klass_name
end

#lock_after_execution_periodObject

Returns the value of attribute lock_after_execution_period.



11
12
13
# File 'lib/resque/unique_by_arity/configuration.rb', line 11

def lock_after_execution_period
  @lock_after_execution_period
end

#log_levelObject

Returns the value of attribute log_level.



8
9
10
# File 'lib/resque/unique_by_arity/configuration.rb', line 8

def log_level
  @log_level
end

#loggerObject

Returns the value of attribute logger.



7
8
9
# File 'lib/resque/unique_by_arity/configuration.rb', line 7

def logger
  @logger
end

#runtime_lock_timeoutObject

Returns the value of attribute runtime_lock_timeout.



12
13
14
# File 'lib/resque/unique_by_arity/configuration.rb', line 12

def runtime_lock_timeout
  @runtime_lock_timeout
end

#unique_across_queuesObject

Returns the value of attribute unique_across_queues.



15
16
17
# File 'lib/resque/unique_by_arity/configuration.rb', line 15

def unique_across_queues
  @unique_across_queues
end

#unique_at_runtimeObject

Returns the value of attribute unique_at_runtime.



13
14
15
# File 'lib/resque/unique_by_arity/configuration.rb', line 13

def unique_at_runtime
  @unique_at_runtime
end

#unique_in_queueObject

Returns the value of attribute unique_in_queue.



14
15
16
# File 'lib/resque/unique_by_arity/configuration.rb', line 14

def unique_in_queue
  @unique_in_queue
end

Instance Method Details

#log(msg) ⇒ Object



47
48
49
# File 'lib/resque/unique_by_arity/configuration.rb', line 47

def log(msg)
  Resque::UniqueByArity.unique_log(msg, self)
end

#skip_arity_validation?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/resque/unique_by_arity/configuration.rb', line 65

def skip_arity_validation?
  SKIPPED_ARITY_VALIDATION_LEVELS.include?(arity_validation)
end

#to_hashObject



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/resque/unique_by_arity/configuration.rb', line 51

def to_hash
  {
      logger: logger,
      log_level: log_level,
      arity_for_uniqueness: arity_for_uniqueness,
      arity_validation: arity_validation,
      lock_after_execution_period: lock_after_execution_period,
      runtime_lock_timeout: runtime_lock_timeout,
      unique_at_runtime: unique_at_runtime,
      unique_in_queue: unique_in_queue,
      unique_across_queues: unique_across_queues
  }
end

#unique_log_levelObject



43
44
45
# File 'lib/resque/unique_by_arity/configuration.rb', line 43

def unique_log_level
  log_level
end

#unique_loggerObject



39
40
41
# File 'lib/resque/unique_by_arity/configuration.rb', line 39

def unique_logger
  logger
end

#validateObject



30
31
32
33
34
35
36
37
# File 'lib/resque/unique_by_arity/configuration.rb', line 30

def validate
  # The default config initialization shouldn't trigger any warnings.
  if base_klass_name && logger
    log "[#{base_klass_name}] :arity_for_uniqueness is set to #{arity_for_uniqueness}, but no uniqueness enforcement was turned on [:unique_at_runtime, :unique_in_queue, :unique_across_queues]" unless unique_at_runtime || unique_in_queue || unique_across_queues
    log "[#{base_klass_name}] :lock_after_execution_period is set to #{lock_after_execution_period}, but :unique_at_runtime is not set" if lock_after_execution_period && !unique_at_runtime
    log "[#{base_klass_name}] :unique_in_queue and :unique_across_queues should not be set at the same time, as :unique_across_queues will always supercede :unique_in_queue" if unique_in_queue && unique_across_queues
  end
end

#validate_arity(klass_string, perform_method) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/resque/unique_by_arity/configuration.rb', line 69

def validate_arity(klass_string, perform_method)
  return true if skip_arity_validation?
  # method.arity -
  #   Returns an indication of the number of arguments accepted by a method.
  #   Returns a non-negative integer for methods that take a fixed number of arguments.
  #   For Ruby methods that take a variable number of arguments, returns -n-1, where n is the number of required arguments.
  #   For methods written in C, returns -1 if the call takes a variable number of arguments.
  # Example:
  #   for perform(opts = {}), method(:perform).arity # => -1
  #   which means that the only valid arity_for_uniqueness is 0
  msg = if perform_method.arity >= 0
          # takes a fixed number of arguments
          # parform(a, b, c) # => arity == 3, so arity for uniqueness can be 0, 1, 2, or 3
          if perform_method.arity < arity_for_uniqueness
            "#{klass_string}.#{perform_method.name} has arity of #{perform_method.arity} which will not work with arity_for_uniqueness of #{arity_for_uniqueness}"
          end
        else
          if (perform_method.arity).abs < arity_for_uniqueness
            # parform(a, b, c, opts = {}) # => arity == -4
            #   and in this case arity for uniqueness can be 0, 1, 2, or 3, because 4 of the arguments are required
            "#{klass_string}.#{perform_method.name} has arity of #{perform_method.arity} which will not work with arity_for_uniqueness of #{arity_for_uniqueness}"
          elsif (required_parameter_names = perform_method.parameters.take_while { |a| a[0] == :req }.map { |b| b[1] }).length < arity_for_uniqueness
            "#{klass_string}.#{perform_method.name} has the following required parameters: #{required_parameter_names}, which is not enough to satisfy the configured arity_for_uniqueness of #{arity_for_uniqueness}"
          end
        end
  case arity_validation
    when :warning then
      log(ColorizedString[msg].red)
    when :error then
      raise ArgumentError, msg
    else
      raise arity_validation, msg
  end if msg
end