services 0.2.5 → 0.2.6

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: 29308e17d5df01f543e985f8aeeb933a0e22e66f
4
- data.tar.gz: 8ccb2f4ca9d250a98a9b78e87d2a5291078a1e00
3
+ metadata.gz: 6f4299a00ac5d36b3ca4eb252b7d389a0b11b36f
4
+ data.tar.gz: 1ddd50f90a9bbda3abea088edc727173ddba9c13
5
5
  SHA512:
6
- metadata.gz: 54d37715aaea3ffbc50852d8ceff00374d58443f3b67a93ee686ec9b88223904ee22fe49cb3ce6d2a36bdc1831f6b490c40ee542f0eca0f5b29634169a237c33
7
- data.tar.gz: c324202d7c4311b6d549f1c764fe817ec1540cd0a3ab02dc9aeacc4493bf479621282aed5dfd8f447c35be7c86a27b2d324714b8a5937d85c29045a6a4a0a1ac
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
- raise 'A variable named @uniqueness_key is already defined. Have you called `check_uniqueness!` twice?' if defined?(@uniqueness_key)
10
- raise 'Could not find @uniqueness_all_args' unless defined?(@uniqueness_all_args)
11
- args = @uniqueness_all_args if args.empty?
12
- @uniqueness_key = uniqueness_key(args)
13
- if similar_service_id = Services.configuration.redis.get(@uniqueness_key)
14
- raise self.class::NotUniqueError, "Service #{self.class} with args #{args} is not unique, a similar service is already running: #{similar_service_id}"
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 @uniqueness_key, 60 * 60, @id
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
- @uniqueness_all_args = args
30
+ @uniqueness_args = args
22
31
  super
23
32
  ensure
24
- Services.configuration.redis.del @uniqueness_key if defined?(@uniqueness_key)
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
- 'services',
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?
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '0.2.5'
2
+ VERSION = '0.2.6'
3
3
  end
@@ -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 was set to check for uniqueness with the default args' do
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.perform_async
124
- expect { UniqueService.call }.to raise_error(UniqueService::NotUniqueError)
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 was set to check for uniqueness with custom args' do
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.perform_async('foo', 'bar', 'baz')
131
- expect { UniqueWithCustomArgsService.call('foo', 'bar', 'pelle') }.to raise_error(UniqueWithCustomArgsService::NotUniqueError)
132
- expect { UniqueWithCustomArgsService.call('foo', 'baz', 'pelle') }.to_not raise_error
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.perform_async
139
- expect { NonUniqueService.call }.to_not raise_error
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
@@ -8,10 +8,21 @@ def wait_for(&block)
8
8
  end
9
9
  end
10
10
 
11
- def wait_for_job_to_run(jid)
12
- wait_for do
13
- Sidekiq::Workers.new.any? do |_, _, work|
14
- work['payload']['jid'] == jid
15
- end
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.5
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 00:00:00.000000000 Z
11
+ date: 2014-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake