Class: Resque::UniqueByArity::Configuration

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

Overview

This class is for configurations that are per job class, not app-wide. Each setting will default to the global config values.

Direct Known Subclasses

GlobalConfiguration

Defined Under Namespace

Classes: Validator

Constant Summary collapse

VALID_ARITY_VALIDATION_LEVELS =
[:warning, :error, :skip, nil, false].freeze
SKIPPED_ARITY_VALIDATION_LEVELS =
[:skip, nil, false].freeze
DEFAULT_LOG_LEVEL =
:debug

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Configuration

Returns a new instance of Configuration.

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/resque/unique_by_arity/configuration.rb', line 30

def initialize(**options)
  @logger = options.key?(:logger) ? options[:logger] : defcon(:logger) || Logger.new(STDOUT)
  @log_level = options.key?(:log_level) ? options[:log_level] : defcon(:log_level) || :debug
  @arity_for_uniqueness = options.key?(:arity_for_uniqueness) ? options[:arity_for_uniqueness] : defcon(:arity_for_uniqueness) || 1
  @arity_for_uniqueness_at_runtime = options.key?(:arity_for_uniqueness_at_runtime) ? options[:arity_for_uniqueness_at_runtime] : defcon(:arity_for_uniqueness_at_runtime) || @arity_for_uniqueness
  @arity_for_uniqueness_in_queue = options.key?(:arity_for_uniqueness_in_queue) ? options[:arity_for_uniqueness_in_queue] : defcon(:arity_for_uniqueness_in_queue) || @arity_for_uniqueness
  @arity_for_uniqueness_across_queues = options.key?(:arity_for_uniqueness_across_queues) ? options[:arity_for_uniqueness_across_queues] : defcon(:arity_for_uniqueness_across_queues) || @arity_for_uniqueness
  @arity_validation = options.key?(:arity_validation) ? options[:arity_validation] : defcon(:arity_validation) || :warning
  raise ArgumentError, "Resque::Plugins::UniqueByArity.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)

  @ttl = options.key?(:ttl) ? options[:ttl] : defcon(:ttl) || nil
  @lock_after_execution_period = options.key?(:lock_after_execution_period) ? options[:lock_after_execution_period] : defcon(:lock_after_execution_period) || nil
  @runtime_lock_timeout = options.key?(:runtime_lock_timeout) ? options[:runtime_lock_timeout] : defcon(:runtime_lock_timeout) || nil
  @runtime_requeue_interval = options.key?(:runtime_requeue_interval) ? options[:runtime_requeue_interval] : defcon(:runtime_requeue_interval) || nil
  @unique_at_runtime = options.key?(:unique_at_runtime) ? options[:unique_at_runtime] : defcon(:unique_at_runtime) || false
  @unique_at_runtime_key_base = options.key?(:unique_at_runtime_key_base) ? options[:unique_at_runtime_key_base] : defcon(:unique_at_runtime_key_base) || nil
  @unique_in_queue_key_base = options.key?(:unique_in_queue_key_base) ? options[:unique_in_queue_key_base] : defcon(:unique_in_queue_key_base) || nil
  @unique_in_queue = options.key?(:unique_in_queue) ? options[:unique_in_queue] : defcon(:unique_in_queue) || false
  @unique_across_queues = options.key?(:unique_across_queues) ? options[:unique_across_queues] : defcon(:unique_across_queues) || false
  # Can't be both unique in queue and unique across queues, since they
  #   must necessarily use different locking key structures, and therefore
  #   can't both be active.
  raise ArgumentError, "Resque::Plugins::UniqueByArity.new requires either one or none of @unique_across_queues and @unique_in_queue to be true. Having both set to true is non-sensical." if @unique_in_queue && @unique_across_queues
  @debug_mode = !!(options.key?(:debug_mode) ? options[:debug_mode] : defcon(:debug_mode))
  if @debug_mode
    # Make sure there is a logger when in debug_mode
    @logger ||= Logger.new(STDOUT)
  end
end

Instance Attribute Details

#arity_for_uniquenessObject

Returns the value of attribute arity_for_uniqueness.



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

def arity_for_uniqueness
  @arity_for_uniqueness
end

#arity_for_uniqueness_across_queuesObject

Returns the value of attribute arity_for_uniqueness_across_queues.



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

def arity_for_uniqueness_across_queues
  @arity_for_uniqueness_across_queues
end

#arity_for_uniqueness_at_runtimeObject

Returns the value of attribute arity_for_uniqueness_at_runtime.



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

def arity_for_uniqueness_at_runtime
  @arity_for_uniqueness_at_runtime
end

#arity_for_uniqueness_in_queueObject

Returns the value of attribute arity_for_uniqueness_in_queue.



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

def arity_for_uniqueness_in_queue
  @arity_for_uniqueness_in_queue
end

#arity_validationObject

Returns the value of attribute arity_validation.



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

def arity_validation
  @arity_validation
end

#base_klass_nameObject

Returns the value of attribute base_klass_name.



27
28
29
# File 'lib/resque/unique_by_arity/configuration.rb', line 27

def base_klass_name
  @base_klass_name
end

#debug_modeObject

Returns the value of attribute debug_mode.



28
29
30
# File 'lib/resque/unique_by_arity/configuration.rb', line 28

def debug_mode
  @debug_mode
end

#lock_after_execution_periodObject

Returns the value of attribute lock_after_execution_period.



18
19
20
# File 'lib/resque/unique_by_arity/configuration.rb', line 18

def lock_after_execution_period
  @lock_after_execution_period
end

#log_levelObject

Returns the value of attribute log_level.



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

def log_level
  @log_level
end

#loggerObject

Returns the value of attribute logger.



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

def logger
  @logger
end

#runtime_lock_timeoutObject

Returns the value of attribute runtime_lock_timeout.



19
20
21
# File 'lib/resque/unique_by_arity/configuration.rb', line 19

def runtime_lock_timeout
  @runtime_lock_timeout
end

#runtime_requeue_intervalObject

Returns the value of attribute runtime_requeue_interval.



20
21
22
# File 'lib/resque/unique_by_arity/configuration.rb', line 20

def runtime_requeue_interval
  @runtime_requeue_interval
end

#ttlObject

Returns the value of attribute ttl.



26
27
28
# File 'lib/resque/unique_by_arity/configuration.rb', line 26

def ttl
  @ttl
end

#unique_across_queuesObject

Returns the value of attribute unique_across_queues.



25
26
27
# File 'lib/resque/unique_by_arity/configuration.rb', line 25

def unique_across_queues
  @unique_across_queues
end

#unique_at_runtimeObject

Returns the value of attribute unique_at_runtime.



21
22
23
# File 'lib/resque/unique_by_arity/configuration.rb', line 21

def unique_at_runtime
  @unique_at_runtime
end

#unique_at_runtime_key_baseObject

Returns the value of attribute unique_at_runtime_key_base.



22
23
24
# File 'lib/resque/unique_by_arity/configuration.rb', line 22

def unique_at_runtime_key_base
  @unique_at_runtime_key_base
end

#unique_in_queueObject

Returns the value of attribute unique_in_queue.



23
24
25
# File 'lib/resque/unique_by_arity/configuration.rb', line 23

def unique_in_queue
  @unique_in_queue
end

#unique_in_queue_key_baseObject

Returns the value of attribute unique_in_queue_key_base.



24
25
26
# File 'lib/resque/unique_by_arity/configuration.rb', line 24

def unique_in_queue_key_base
  @unique_in_queue_key_base
end

Instance Method Details

#defcon(sym) ⇒ Object



132
133
134
# File 'lib/resque/unique_by_arity/configuration.rb', line 132

def defcon(sym)
  Resque::UniqueByArity.configuration.send(sym)
end

#log(msg) ⇒ Object



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

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

#skip_arity_validation?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/resque/unique_by_arity/configuration.rb', line 90

def skip_arity_validation?
  SKIPPED_ARITY_VALIDATION_LEVELS.include?(arity_validation)
end

#to_hashObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/resque/unique_by_arity/configuration.rb', line 70

def to_hash
  {
    log_level: log_level,
    logger: logger,
    arity_for_uniqueness: arity_for_uniqueness,
    arity_for_uniqueness_at_runtime: arity_for_uniqueness_at_runtime,
    arity_for_uniqueness_in_queue: arity_for_uniqueness_in_queue,
    arity_for_uniqueness_across_queues: arity_for_uniqueness_across_queues,
    arity_validation: arity_validation,
    base_klass_name: base_klass_name,
    debug_mode: debug_mode,
    lock_after_execution_period: lock_after_execution_period,
    runtime_lock_timeout: runtime_lock_timeout,
    ttl: ttl,
    unique_at_runtime: unique_at_runtime,
    unique_in_queue: unique_in_queue,
    unique_across_queues: unique_across_queues
  }
end

#validateObject



60
61
62
63
64
# File 'lib/resque/unique_by_arity/configuration.rb', line 60

def validate
  return unless base_klass_name && logger

  Validator.log_warnings(self)
end

#validate_arity(klass_string, perform_method) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/resque/unique_by_arity/configuration.rb', line 94

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
  if msg
    case arity_validation
    when :warning
      log(msg)
    when :error
      raise ArgumentError, msg
    else
      raise arity_validation, msg
    end
  end
end