resque-unique_by_arity 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afaba7f0ac02c1b80d222b733d7caf16ce7b2d42
4
- data.tar.gz: 1d6cc14ca863aa92d5f736d4741e479a6abc3759
3
+ metadata.gz: 06ef1c526f5dea1a56e51bbf8053e41854ec9e94
4
+ data.tar.gz: 8bbd6cae274b5a245019e88b6297672eb66bfb92
5
5
  SHA512:
6
- metadata.gz: 37655993edb61c5c6f26880e41519374ff4913b67ec32ac7979a108be31aec8773bb67d06b0485b55e648b442a43a993fb774a5665c284ef522f747f73492d84
7
- data.tar.gz: 1b0019d9c73ae0e1e504d90871b4603474071d4c03f44d7dbcce1b7d1d5824a74d9bd68a46237e9064b009be588e99c6e08bd148857ec0b3c0c26c28c0f9ea67
6
+ metadata.gz: '08fec6b73c8f0cb6d28a82d4b0b639835088dbe180f3f28ec86201b2256687dc92839d2added60f36a64b7930c2d0bea132412e2c7787e17ab8251c37f500f5f'
7
+ data.tar.gz: bd024532330e4b82dac8e41f6b26c5747ec68f36a3a3a7db468c027a9e369dc003836ab150c20d18c36628dddc3b7ebc9ad33f568c508ae51378002937759df8
data/README.md CHANGED
@@ -12,6 +12,7 @@ class MyJob
12
12
  include UniqueByArity::Cop.new(
13
13
  arity_for_uniqueness: 1,
14
14
  lock_after_execution_period: 60,
15
+ runtime_lock_timeout: 60 * 60 * 24 * 5, # 5 days
15
16
  unique_at_runtime: true,
16
17
  unique_in_queue: true
17
18
  )
@@ -52,6 +53,28 @@ class MyJob
52
53
  end
53
54
  ```
54
55
 
56
+ #### Arity For Uniqueness Validation
57
+
58
+ Want this gem to tell you when it is misconfigured? It can.
59
+
60
+ ```ruby
61
+ class MyJob
62
+ include UniqueByArity::Cop.new(
63
+ arity_for_uniqueness: 3,
64
+ arity_validation: :warning, # or :skip, :error, or an error class to be raised, e.g. RuntimeError
65
+ unique_at_runtime: true
66
+ )
67
+ def self.perform(my, cat, opts = {})
68
+ # Because the third argument is optional the arity valdiation will not approve.
69
+ # Arguments to be considered for uniqueness should be required arguments.
70
+ # The warning log might look like:
71
+ #
72
+ # MyJob.perform has the following required parameters: [:my, :cat], which is not enough to satisfy the configured arity_for_uniqueness of 3
73
+ end
74
+ end
75
+ ```
76
+
77
+
55
78
  ### Lock After Execution
56
79
 
57
80
  Give the job a break after it finishes running, and don't allow another of the same, with matching args @ configured arity, to start within X seconds.
@@ -66,6 +89,20 @@ class MyJob
66
89
  end
67
90
  ```
68
91
 
92
+ ### Runtime Lock Timeout
93
+
94
+ If runtime lock keys get stale, they will expire on their own after some period. You can set the expiration period on a per class basis.
95
+
96
+ ```ruby
97
+ class MyJob
98
+ include UniqueByArity::Cop.new(
99
+ arity_for_uniqueness: 1,
100
+ runtime_lock_timeout: 60 * 60 * 24 * 5, # 5 days
101
+ unique_at_runtime: true
102
+ )
103
+ end
104
+ ```
105
+
69
106
  ### Unique At Runtime (across all queues)
70
107
 
71
108
  Prevent your app from running a job that is already running.
@@ -119,6 +156,7 @@ class MyJob
119
156
  include UniqueByArity::Cop.new(
120
157
  arity_for_uniqueness: 1,
121
158
  unique_at_runtime: true,
159
+ runtime_lock_timeout: 60 * 60 * 24 * 5, # 5 days
122
160
  unique_in_queue: true
123
161
  )
124
162
  end
@@ -134,6 +172,7 @@ class MyJob
134
172
  include UniqueByArity::Cop.new(
135
173
  arity_for_uniqueness: 1,
136
174
  unique_at_runtime: true,
175
+ runtime_lock_timeout: 60 * 60 * 24 * 5, # 5 days
137
176
  unique_across_queues: true
138
177
  )
139
178
  end
@@ -8,6 +8,7 @@ module Resque
8
8
  attr_accessor :arity_for_uniqueness
9
9
  attr_accessor :arity_validation
10
10
  attr_accessor :lock_after_execution_period
11
+ attr_accessor :runtime_lock_timeout
11
12
  attr_accessor :unique_at_runtime
12
13
  attr_accessor :unique_in_queue
13
14
  attr_accessor :unique_across_queues
@@ -15,9 +16,10 @@ module Resque
15
16
  @logger = options.key?(:logger) ? options[:logger] : Logger.new(STDOUT)
16
17
  @log_level = options.key?(:log_level) ? options[:log_level] : :debug
17
18
  @arity_for_uniqueness = options.key?(:arity_for_uniqueness) ? options[:arity_for_uniqueness] : 1
18
- @arity_validation = options.key?(:arity_validation) ? options[:arity_validation] : false
19
+ @arity_validation = options.key?(:arity_validation) ? options[:arity_validation] : :warning
19
20
  raise ArgumentError, "UniqueByArity::Cop.new requires arity_validation values of nil, false, :warning, :error, or an class descending from Exception but the value is #{@arity_validation} (#{@arity_validation.class})" unless VALID_ARITY_VALIDATION_LEVELS.include?(@arity_validation) || @arity_validation.ancestors.include?(Exception)
20
21
  @lock_after_execution_period = options.key?(:lock_after_execution_period) ? options[:lock_after_execution_period] : nil
22
+ @runtime_lock_timeout = options.key?(:runtime_lock_timeout) ? options[:runtime_lock_timeout] : nil
21
23
  @unique_at_runtime = options.key?(:unique_at_runtime) ? options[:unique_at_runtime] : false
22
24
  @unique_in_queue = options.key?(:unique_in_queue) ? options[:unique_in_queue] : false
23
25
  @unique_across_queues = options.key?(:unique_across_queues) ? options[:unique_across_queues] : false
@@ -47,14 +49,19 @@ module Resque
47
49
  log_level: log_level,
48
50
  arity_for_uniqueness: arity_for_uniqueness,
49
51
  lock_after_execution_period: lock_after_execution_period,
52
+ runtime_lock_timeout: runtime_lock_timeout,
50
53
  unique_at_runtime: unique_at_runtime,
51
54
  unique_in_queue: unique_in_queue,
52
55
  unique_across_queues: unique_across_queues
53
56
  }
54
57
  end
55
58
 
59
+ def skip_arity_validation?
60
+ arity_validation == :skip
61
+ end
62
+
56
63
  def validate_arity(klass_string, perform_method)
57
- return true unless arity_validation
64
+ return true if skip_arity_validation?
58
65
  # method.arity -
59
66
  # Returns an indication of the number of arguments accepted by a method.
60
67
  # Returns a non-negative integer for methods that take a fixed number of arguments.
@@ -63,14 +70,24 @@ module Resque
63
70
  # Example:
64
71
  # for perform(opts = {}), method(:perform).arity # => -1
65
72
  # which means that the only valid arity_for_uniqueness is 0
66
- msg = if perform_method.arity < (arity_for_uniqueness - 1)
67
- "#{klass_string}.#{perform_method.name} has arity of #{perform_method.arity} which will not work with arity_for_uniqueness of #{arity_for_uniqueness}"
68
- elsif (required_parameter_names = perform_method.parameters.take_while { |a| a[0] == :req }.map { |b| b[1] }).length < arity_for_uniqueness
69
- "#{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}"
73
+ msg = if perform_method.arity >= 0
74
+ # takes a fixed number of arguments
75
+ # parform(a, b, c) # => arity == 3, so arity for uniqueness can be 0, 1, 2, or 3
76
+ if perform_method.arity < arity_for_uniqueness
77
+ "#{klass_string}.#{perform_method.name} has arity of #{perform_method.arity} which will not work with arity_for_uniqueness of #{arity_for_uniqueness}"
78
+ end
79
+ else
80
+ if (perform_method.arity).abs < arity_for_uniqueness
81
+ # parform(a, b, c, opts = {}) # => arity == -4
82
+ # and in this case arity for uniqueness can be 0, 1, 2, or 3, because 4 of the arguments are required
83
+ "#{klass_string}.#{perform_method.name} has arity of #{perform_method.arity} which will not work with arity_for_uniqueness of #{arity_for_uniqueness}"
84
+ elsif (required_parameter_names = perform_method.parameters.take_while { |a| a[0] == :req }.map { |b| b[1] }).length < arity_for_uniqueness
85
+ "#{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}"
86
+ end
70
87
  end
71
88
  case arity_validation
72
89
  when :warning then
73
- log(msg)
90
+ log(ColorizedString[msg].red)
74
91
  when :error then
75
92
  raise ArgumentError, msg
76
93
  else
@@ -22,7 +22,7 @@ module Resque
22
22
  # This will override methods from both plugins above, if configured for both
23
23
  base.send(:extend, uniqueness_cop_module)
24
24
 
25
- base.include Resque::UniqueByArity::Validation if @configuration.arity_validation
25
+ base.include Resque::UniqueByArity::Validation unless @configuration.skip_arity_validation?
26
26
  end
27
27
  end
28
28
  end
@@ -25,7 +25,11 @@ module Resque
25
25
  if configuration.lock_after_execution_period
26
26
  self.instance_variable_set(:@lock_after_execution_period, configuration.lock_after_execution_period)
27
27
  end
28
-
28
+
29
+ if configuration.runtime_lock_timeout
30
+ self.instance_variable_set(:@runtime_lock_timeout, configuration.runtime_lock_timeout)
31
+ end
32
+
29
33
  if configuration.unique_in_queue || configuration.unique_across_queues
30
34
  ### Gem: resque_solo
31
35
  ### Plugin Name: Resque::Plugins::UniqueJob
@@ -76,6 +80,7 @@ module Resque
76
80
  if configuration.unique_at_runtime
77
81
  # @return [String] the Redis namespace of the key used to enforce uniqueness (at runtime)
78
82
  define_method(:runtime_key_namespace) do
83
+ puts "runtime_key_namespace for #{self}"
79
84
  "unique_at_runtime:#{self}"
80
85
  end
81
86
  # Returns a string, used by Resque::Plugins::UniqueAtRuntime, that will be used as the redis key
@@ -2,8 +2,10 @@ module Resque
2
2
  module UniqueByArity
3
3
  module Validation
4
4
  def self.included(base)
5
- @um = base.method(:perform)
6
- base.uniq_config.validate_arity(base.to_s, @um) if base.uniq_config.arity_validation
5
+ unless base.uniq_config.skip_arity_validation?
6
+ um = base.method(:perform)
7
+ base.uniq_config.validate_arity(base.to_s, um)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,5 +1,5 @@
1
1
  module Resque
2
2
  module UniqueByArity
3
- VERSION = "1.0.8"
3
+ VERSION = "1.0.9"
4
4
  end
5
5
  end
@@ -25,7 +25,7 @@ require "resque/unique_by_arity/validation"
25
25
  module Resque
26
26
  module UniqueByArity
27
27
  def unique_log(message, config_proxy = nil)
28
- config_proxy ||= self
28
+ config_proxy ||= uniqueness_configuration
29
29
  config_proxy.unique_logger.send(config_proxy.unique_log_level, message) if config_proxy.unique_logger
30
30
  end
31
31
 
@@ -72,6 +72,12 @@ module Resque
72
72
  def uniqueness_lock_after_execution_period=(lock_after_execution_period)
73
73
  @uniqueness_configuration.lock_after_execution_period = lock_after_execution_period
74
74
  end
75
+ def uniqueness_runtime_lock_timeout
76
+ @uniqueness_configuration.runtime_lock_timeout
77
+ end
78
+ def uniqueness_runtime_lock_timeout=(runtime_lock_timeout)
79
+ @uniqueness_configuration.runtime_lock_timeout = runtime_lock_timeout
80
+ end
75
81
  def uniqueness_unique_at_runtime
76
82
  @uniqueness_configuration.unique_at_runtime
77
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-unique_by_arity
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-02 00:00:00.000000000 Z
11
+ date: 2017-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: resque-unique_at_runtime