services 0.2.11 → 0.2.12
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/base.rb +2 -2
- data/lib/services/modules/uniqueness_checker.rb +23 -10
- data/lib/services/version.rb +1 -1
- data/spec/services/modules/uniqueness_checker_spec.rb +21 -20
- data/spec/spec_helper.rb +24 -10
- 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: fa15ea76009e9ba974b7e3faf90a467368917660
|
4
|
+
data.tar.gz: 5c0dcc6db009e65fb210e9883feb604329d1bf5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3684cdccaf566dae3c4f018127efe9d947692488ec30bb714c8ebaca9d134dd876750483b6794b4bc9b26a589966e0e533a455b98e4ac1bdcbb85fcb810c682
|
7
|
+
data.tar.gz: 5c98b4049291181ccd59abf71c6ade54a8aac194521ed5c2ad2c9e70380ee88930ebb94734138fea1496229491ee88d231c21401ecd46c4e0719f50f7f6356f5
|
data/lib/services/base.rb
CHANGED
@@ -25,7 +25,7 @@ module Services
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def find_objects(ids_or_objects, klass =
|
28
|
+
def find_objects(ids_or_objects, klass = service_class)
|
29
29
|
ids_or_objects = Array(ids_or_objects)
|
30
30
|
ids, objects = ids_or_objects.grep(Fixnum), ids_or_objects.grep(klass)
|
31
31
|
if ids.size + objects.size < ids_or_objects.size
|
@@ -52,7 +52,7 @@ module Services
|
|
52
52
|
end.first
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def service_class
|
56
56
|
self.class.to_s[/Services::([^:]+)/, 1].singularize.constantize
|
57
57
|
rescue
|
58
58
|
raise "Could not determine service class from #{self.class}"
|
@@ -27,21 +27,19 @@ module Services
|
|
27
27
|
raise "A uniqueness key with args #{@uniqueness_args.inspect} already exists." if @uniqueness_keys && @uniqueness_keys.include?(new_uniqueness_key)
|
28
28
|
if @similar_service_id = Services.configuration.redis.get(new_uniqueness_key)
|
29
29
|
case on_error.to_sym
|
30
|
-
when :ignore
|
31
|
-
false
|
32
30
|
when :fail
|
33
31
|
raise_non_unique_error
|
34
32
|
when :reschedule
|
35
|
-
error_count = (Services.configuration.redis.get(error_count_key) || 0).to_i
|
36
|
-
if error_count >= MAX_RETRIES
|
33
|
+
@error_count = (Services.configuration.redis.get(error_count_key) || 0).to_i
|
34
|
+
if @error_count >= MAX_RETRIES
|
37
35
|
raise_non_unique_error
|
38
36
|
else
|
39
|
-
error_count += 1
|
40
|
-
|
41
|
-
Services.configuration.redis.setex error_count_key, retry_delay
|
42
|
-
false
|
37
|
+
@error_count += 1
|
38
|
+
reschedule
|
39
|
+
Services.configuration.redis.setex error_count_key, retry_delay + ONE_HOUR, @error_count
|
43
40
|
end
|
44
41
|
end
|
42
|
+
false
|
45
43
|
else
|
46
44
|
@uniqueness_keys ||= []
|
47
45
|
@uniqueness_keys << new_uniqueness_key
|
@@ -66,6 +64,21 @@ module Services
|
|
66
64
|
raise self.class::NotUniqueError, message
|
67
65
|
end
|
68
66
|
|
67
|
+
def reschedule
|
68
|
+
# Convert service args to fixnums first
|
69
|
+
reschedule_args = @service_args.map do |arg|
|
70
|
+
case arg
|
71
|
+
when Fixnum, String, TrueClass, FalseClass, NilClass
|
72
|
+
arg
|
73
|
+
when service_class && arg.respond_to?(:id)
|
74
|
+
arg.id
|
75
|
+
else
|
76
|
+
raise "Don't know how to convert arg #{arg.inspect} for rescheduling."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
self.class.perform_in retry_delay, *reschedule_args
|
80
|
+
end
|
81
|
+
|
69
82
|
def uniqueness_key(args)
|
70
83
|
[
|
71
84
|
KEY_PREFIX,
|
@@ -85,8 +98,8 @@ module Services
|
|
85
98
|
end.join(':')
|
86
99
|
end
|
87
100
|
|
88
|
-
def retry_delay
|
89
|
-
(error_count ** 3) + 5
|
101
|
+
def retry_delay
|
102
|
+
(@error_count ** 3) + 5
|
90
103
|
end
|
91
104
|
end
|
92
105
|
end
|
data/lib/services/version.rb
CHANGED
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
shared_examples 'checking the uniqueness properly' do
|
4
4
|
it 'notices when the same job is executed multiple times' do
|
5
|
-
# Check that error is raised when on_error is "fail"
|
6
5
|
wait_for_job_to_run_and_finish service, *args, 'fail', true do
|
6
|
+
# Check that error is raised when on_error is "fail"
|
7
7
|
if defined?(fail_args)
|
8
8
|
3.times do
|
9
9
|
fail_args.each do |fail_arg_group|
|
@@ -40,57 +40,58 @@ shared_examples 'checking the uniqueness properly' do
|
|
40
40
|
3.times do
|
41
41
|
fail_args.each do |fail_arg_group|
|
42
42
|
expect(service).to receive(:perform_in).with(an_instance_of(Fixnum), *fail_arg_group, 'reschedule', false)
|
43
|
-
service.call(*fail_arg_group, 'reschedule', false)
|
43
|
+
expect { service.call(*fail_arg_group, 'reschedule', false) }.to_not raise_error
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
47
47
|
if defined?(pass_args)
|
48
48
|
3.times do
|
49
49
|
pass_args.each do |pass_arg_group|
|
50
|
+
expect(service).to_not receive(:perform_in)
|
50
51
|
expect { service.call(*pass_arg_group, 'reschedule', false) }.to_not raise_error
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
56
|
+
|
57
|
+
# Check that all Redis keys are deleted
|
58
|
+
key_pattern = "#{described_class::KEY_PREFIX}*"
|
59
|
+
expect(Services.configuration.redis.keys(key_pattern)).to be_empty
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
58
63
|
describe Services::Base::UniquenessChecker do
|
59
64
|
context 'when the service checks for uniqueness with the default args' do
|
60
65
|
it_behaves_like 'checking the uniqueness properly' do
|
61
|
-
let(:service)
|
62
|
-
let(:args)
|
63
|
-
let(:fail_args)
|
64
|
-
let(:keys_after_start) { 1 }
|
66
|
+
let(:service) { UniqueService }
|
67
|
+
let(:args) { [] }
|
68
|
+
let(:fail_args) { [] }
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
68
72
|
context 'when the service checks for uniqueness with custom args' do
|
69
73
|
it_behaves_like 'checking the uniqueness properly' do
|
70
|
-
let(:service)
|
71
|
-
let(:args)
|
72
|
-
let(:fail_args)
|
73
|
-
let(:pass_args)
|
74
|
-
let(:keys_after_start) { 1 }
|
74
|
+
let(:service) { UniqueWithCustomArgsService }
|
75
|
+
let(:args) { ['foo', 1, 'bar'] }
|
76
|
+
let(:fail_args) { [['foo', 1, 'pelle']] }
|
77
|
+
let(:pass_args) { [['foo', 2, 'bar']] }
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
78
81
|
context 'when the service checks for uniqueness multiple times' do
|
79
82
|
it_behaves_like 'checking the uniqueness properly' do
|
80
|
-
let(:service)
|
81
|
-
let(:args)
|
82
|
-
let(:fail_args)
|
83
|
-
let(:pass_args)
|
84
|
-
let(:keys_after_start) { 3 }
|
83
|
+
let(:service) { UniqueMultipleService }
|
84
|
+
let(:args) { ['foo', 1, true] }
|
85
|
+
let(:fail_args) { args.map { |arg| [arg] } }
|
86
|
+
let(:pass_args) { [%w(pelle)] }
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
90
|
context 'when the service does not check for uniqueness' do
|
89
91
|
it_behaves_like 'checking the uniqueness properly' do
|
90
|
-
let(:service)
|
91
|
-
let(:args)
|
92
|
-
let(:pass_args)
|
93
|
-
let(:keys_after_start) { 0 }
|
92
|
+
let(:service) { NonUniqueService }
|
93
|
+
let(:args) { [] }
|
94
|
+
let(:pass_args) { [] }
|
94
95
|
end
|
95
96
|
end
|
96
97
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,6 +12,9 @@ log_dir = support_dir.join('log')
|
|
12
12
|
|
13
13
|
CALL_PROXY_SOURCE = support_dir.join('call_proxy.rb')
|
14
14
|
CALL_PROXY_DESTINATION = PROJECT_ROOT.join('lib', 'services', 'call_proxy.rb')
|
15
|
+
WAIT = 0.5
|
16
|
+
START_TIMEOUT = 5
|
17
|
+
STOP_TIMEOUT = 20
|
15
18
|
|
16
19
|
Dir[support_dir.join('**', '*.rb')].each { |f| require f }
|
17
20
|
|
@@ -71,9 +74,18 @@ RSpec.configure do |config|
|
|
71
74
|
FileUtils.cp CALL_PROXY_SOURCE, CALL_PROXY_DESTINATION
|
72
75
|
|
73
76
|
# Wait until Redis and Sidekiq are started
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
+
@processes = {
|
78
|
+
'Sidekiq' => sidekiq_pidfile
|
79
|
+
}
|
80
|
+
@processes['Redis'] = redis_pidfile unless ENV['TRAVIS']
|
81
|
+
@processes.each do |process, pidfile|
|
82
|
+
i = 0
|
83
|
+
while !File.exist?(pidfile)
|
84
|
+
puts "Waiting for #{process} to start..."
|
85
|
+
sleep WAIT
|
86
|
+
i += WAIT
|
87
|
+
raise "#{process} didn't start in #{i} seconds." if i >= START_TIMEOUT
|
88
|
+
end
|
77
89
|
end
|
78
90
|
end
|
79
91
|
|
@@ -83,18 +95,20 @@ RSpec.configure do |config|
|
|
83
95
|
|
84
96
|
# Stop Sidekiq
|
85
97
|
system "bundle exec sidekiqctl stop #{sidekiq_pidfile} #{sidekiq_timeout}"
|
86
|
-
while File.exist?(sidekiq_pidfile)
|
87
|
-
puts 'Waiting for Sidekiq to shut down...'
|
88
|
-
sleep 0.5
|
89
|
-
end
|
90
98
|
|
91
99
|
unless ENV['TRAVIS']
|
92
100
|
# Stop Redis
|
93
101
|
redis_cli = support_dir.join('redis-cli')
|
94
102
|
system "#{redis_cli} -p #{redis_port} shutdown"
|
95
|
-
|
96
|
-
|
97
|
-
|
103
|
+
end
|
104
|
+
|
105
|
+
@processes.each do |process, pidfile|
|
106
|
+
i = 0
|
107
|
+
while File.exist?(pidfile)
|
108
|
+
puts "Waiting for #{process} to stop..."
|
109
|
+
sleep WAIT
|
110
|
+
i += WAIT
|
111
|
+
raise "#{process} didn't stop in #{i} seconds." if i >= STOP_TIMEOUT
|
98
112
|
end
|
99
113
|
end
|
100
114
|
|
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.12
|
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-
|
11
|
+
date: 2014-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|