services 0.2.5 → 0.2.6
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 +4 -4
- data/lib/services/modules/uniqueness_checker.rb +19 -11
- data/lib/services/version.rb +1 -1
- data/spec/services/base_spec.rb +38 -9
- data/spec/support/helpers.rb +16 -5
- data/spec/support/test_services.rb +9 -0
- 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: 6f4299a00ac5d36b3ca4eb252b7d389a0b11b36f
|
4
|
+
data.tar.gz: 1ddd50f90a9bbda3abea088edc727173ddba9c13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 848c4ee5ee12f5e5f0830716d49a16d4f9733620faf5be6dc1623d8ead6bfffbdbcb296d540f69ce1484efa9a83ab9ab504f388b8a9e56e7c5d15a8125ecba85
|
7
|
+
data.tar.gz: a53a702dc0f76feffc578e28488f0d10857854f9d13beaecf2702a362be31ba77410b0c3ba52e2292e6cb9536db96cb9b76007d5d220eeaa4a2a81c403f26b51
|
@@ -1,35 +1,43 @@
|
|
1
1
|
module Services
|
2
2
|
class Base
|
3
3
|
module UniquenessChecker
|
4
|
+
KEY_PREFIX = %w(
|
5
|
+
services
|
6
|
+
uniqueness
|
7
|
+
).join(':')
|
8
|
+
|
4
9
|
def self.prepended(mod)
|
5
10
|
mod.const_set :NotUniqueError, Class.new(mod::Error)
|
6
11
|
end
|
7
12
|
|
8
13
|
def check_uniqueness!(*args)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
if args.empty?
|
15
|
+
raise 'Could not find uniqueness args' unless defined?(@uniqueness_args)
|
16
|
+
args = @uniqueness_args
|
17
|
+
end
|
18
|
+
@uniqueness_keys ||= []
|
19
|
+
new_uniqueness_key = uniqueness_key(args)
|
20
|
+
raise "A uniqueness key with args #{args.inspect} already exists." if @uniqueness_keys.include?(new_uniqueness_key)
|
21
|
+
@uniqueness_keys << new_uniqueness_key
|
22
|
+
if similar_service_id = Services.configuration.redis.get(new_uniqueness_key)
|
23
|
+
raise self.class::NotUniqueError, "Service #{self.class} with uniqueness args #{args} is not unique, a similar service is already running: #{similar_service_id}"
|
15
24
|
else
|
16
|
-
Services.configuration.redis.setex
|
25
|
+
Services.configuration.redis.setex new_uniqueness_key, 60 * 60, @id
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
29
|
def call(*args)
|
21
|
-
@
|
30
|
+
@uniqueness_args = args
|
22
31
|
super
|
23
32
|
ensure
|
24
|
-
Services.configuration.redis.del @
|
33
|
+
Services.configuration.redis.del @uniqueness_keys if defined?(@uniqueness_keys)
|
25
34
|
end
|
26
35
|
|
27
36
|
private
|
28
37
|
|
29
38
|
def uniqueness_key(args)
|
30
39
|
[
|
31
|
-
|
32
|
-
'uniqueness',
|
40
|
+
KEY_PREFIX,
|
33
41
|
self.class.to_s
|
34
42
|
].tap do |key|
|
35
43
|
key << Digest::MD5.hexdigest(args.to_s) unless args.empty?
|
data/lib/services/version.rb
CHANGED
data/spec/services/base_spec.rb
CHANGED
@@ -118,25 +118,54 @@ describe Services::Base do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
context 'checking for uniqueness' do
|
121
|
-
context 'when the service
|
121
|
+
context 'when the service checks for uniqueness with the default args' do
|
122
122
|
it 'raises an error when the same job is executed twice' do
|
123
|
-
wait_for_job_to_run UniqueService
|
124
|
-
|
123
|
+
wait_for_job_to_run UniqueService do
|
124
|
+
expect { UniqueService.call }.to raise_error(UniqueService::NotUniqueError)
|
125
|
+
end
|
125
126
|
end
|
126
127
|
end
|
127
128
|
|
128
|
-
context 'when the service
|
129
|
+
context 'when the service checks for uniqueness with custom args' do
|
129
130
|
it 'raises an error when a job with the same custom args is executed twice' do
|
130
|
-
wait_for_job_to_run UniqueWithCustomArgsService
|
131
|
-
|
132
|
-
|
131
|
+
wait_for_job_to_run UniqueWithCustomArgsService, 'foo', 'bar', 'baz' do
|
132
|
+
expect { UniqueWithCustomArgsService.call('foo', 'bar', 'pelle') }.to raise_error(UniqueWithCustomArgsService::NotUniqueError)
|
133
|
+
expect { UniqueWithCustomArgsService.call('foo', 'baz', 'pelle') }.to_not raise_error
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when the service checks for uniqueness multiple times' do
|
139
|
+
let(:args) { %w(foo bar baz) }
|
140
|
+
|
141
|
+
it 'raises an error when one of the checks fails' do
|
142
|
+
wait_for_job_to_run UniqueMultipleService, *args do
|
143
|
+
args.each do |arg|
|
144
|
+
expect { UniqueMultipleService.call(arg) }.to raise_error(UniqueMultipleService::NotUniqueError)
|
145
|
+
end
|
146
|
+
expect { UniqueMultipleService.call('pelle') }.to_not raise_error
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'does not leave any Redis keys behind' do
|
151
|
+
expect do
|
152
|
+
wait_for_job_to_run_and_finish UniqueMultipleService, *args do
|
153
|
+
args.each do |arg|
|
154
|
+
UniqueMultipleService.call(arg) rescue nil
|
155
|
+
end
|
156
|
+
UniqueMultipleService.call('pelle')
|
157
|
+
end
|
158
|
+
end.to_not change {
|
159
|
+
Services.configuration.redis.keys("*#{Services::Base::UniquenessChecker::KEY_PREFIX}*").count
|
160
|
+
}
|
133
161
|
end
|
134
162
|
end
|
135
163
|
|
136
164
|
context 'when the service was not set to check for uniqueness' do
|
137
165
|
it 'does not raise an error when the same job is executed twice' do
|
138
|
-
wait_for_job_to_run NonUniqueService
|
139
|
-
|
166
|
+
wait_for_job_to_run NonUniqueService do
|
167
|
+
expect { NonUniqueService.call }.to_not raise_error
|
168
|
+
end
|
140
169
|
end
|
141
170
|
end
|
142
171
|
end
|
data/spec/support/helpers.rb
CHANGED
@@ -8,10 +8,21 @@ def wait_for(&block)
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def worker_with_jid(jid)
|
12
|
+
Sidekiq::Workers.new.detect do |_, _, work|
|
13
|
+
work['payload']['jid'] == jid
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def wait_for_job_to_run(job_class, *args, &block)
|
18
|
+
job_class.perform_async(*args).tap do |jid|
|
19
|
+
wait_for { worker_with_jid(jid) }
|
20
|
+
block.call if block_given?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def wait_for_job_to_run_and_finish(job_class, *args, &block)
|
25
|
+
wait_for_job_to_run(job_class, *args, &block).tap do |jid|
|
26
|
+
wait_for { worker_with_jid(jid).nil? }
|
16
27
|
end
|
17
28
|
end
|
@@ -67,6 +67,15 @@ class UniqueWithCustomArgsService < Services::Base
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
class UniqueMultipleService < Services::Base
|
71
|
+
def call(*args)
|
72
|
+
args.each do |arg|
|
73
|
+
check_uniqueness! arg
|
74
|
+
end
|
75
|
+
sleep 0.5
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
70
79
|
class NonUniqueService < Services::Base
|
71
80
|
def call
|
72
81
|
sleep 0.5
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manuel Meurer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|