resque-unique_by_arity 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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