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 +4 -4
- data/README.md +39 -0
- data/lib/resque/unique_by_arity/configuration.rb +24 -7
- data/lib/resque/unique_by_arity/cop.rb +1 -1
- data/lib/resque/unique_by_arity/cop_modulizer.rb +6 -1
- data/lib/resque/unique_by_arity/validation.rb +4 -2
- data/lib/resque/unique_by_arity/version.rb +1 -1
- data/lib/resque/unique_by_arity.rb +7 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06ef1c526f5dea1a56e51bbf8053e41854ec9e94
|
4
|
+
data.tar.gz: 8bbd6cae274b5a245019e88b6297672eb66bfb92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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] :
|
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
|
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
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
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
|
-
|
6
|
-
|
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
|
@@ -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 ||=
|
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.
|
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-
|
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
|