services 2.1.0 → 2.2.3

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: 97b67785d62fb93ba36e511d6e6a2a7f1f949468
4
- data.tar.gz: 95180d3cc52cdb8e86a12f8937b46967739adb1b
3
+ metadata.gz: 1e3f42f5b3d4869497acf2e3405f0f278b25582d
4
+ data.tar.gz: 8c4d047373b919125c3117da284fd345f7a81816
5
5
  SHA512:
6
- metadata.gz: 3610f3f8aa0b79110ea17583191f4f5dec5a976eb8b9a6fc632bf614aa5a96d0b38508ecb80e1c6f4f35a7b65198c6c341634c171f53f732fce6278b38505580
7
- data.tar.gz: d43bca63c94f9ef81c24752720c5e5d3d08c352c35c5c2905090a956882b20ffb0427908aa1bdc863ad5f4ddee7b476c2909ba1b57eef88fd731471fab363445
6
+ metadata.gz: 3c776d68b4a336b6a7a04a0003137a176447d1a13a0061c25d3e78806b2243ee81c1cec2a46951be2713acabef16d734681a911cb81eb2ca4a2667b5ea1ae4df
7
+ data.tar.gz: 933e0c58c79076b20ab1448b7c6105154703b5aea272ef590d17002d4b092fea4cc5149fd385d1b8d1d6c1af7114fa6446501ef104ac141ec09ed58a4e95a4db
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.2.3
2
+
3
+ * Add `on_error` option `return` to uniqueness checker
4
+
1
5
  ## 2.1.0
2
6
 
3
7
  * Add `find_ids` and `find_id` helpers to base service
data/lib/services/base.rb CHANGED
@@ -73,9 +73,6 @@ module Services
73
73
 
74
74
  def controller
75
75
  @controller ||= begin
76
- # raise "You must use Rails to use the `controller` helper." unless defined?(Rails)
77
- # host = Rails.application.routes.default_url_options[:host] || ActionMailer::Base.default_url_options[:host]
78
- # Rails.application.routes.default_url_options[:host]
79
76
  raise 'Please configure host.' if Services.configuration.host.nil?
80
77
  request = ActionDispatch::TestRequest.new
81
78
  request.host = Services.configuration.host
@@ -12,16 +12,18 @@ module Services
12
12
  end
13
13
 
14
14
  module ClassMethods
15
- @call_logging_disabled = false
15
+ @_call_logging_disabled = false
16
16
 
17
- attr_accessor :call_logging_disabled
17
+ def call_logging_disabled
18
+ @_call_logging_disabled
19
+ end
18
20
 
19
21
  def disable_call_logging
20
- @call_logging_disabled = true
22
+ @_call_logging_disabled = true
21
23
  end
22
24
 
23
25
  def enable_call_logging
24
- @call_logging_disabled = false
26
+ @_call_logging_disabled = false
25
27
  end
26
28
  end
27
29
 
@@ -10,6 +10,7 @@ module Services
10
10
  fail
11
11
  ignore
12
12
  reschedule
13
+ return
13
14
  )
14
15
 
15
16
  MAX_RETRIES = 10
@@ -21,45 +22,56 @@ module Services
21
22
 
22
23
  def check_uniqueness(*args, on_error: :fail)
23
24
  raise "on_error must be one of #{ON_ERROR.join(', ')}, but was #{on_error}" unless ON_ERROR.include?(on_error.to_sym)
24
- raise 'Service args not found.' if @service_args.nil?
25
- @uniqueness_args = args.empty? ? @service_args : args
26
- new_uniqueness_key = uniqueness_key(@uniqueness_args)
27
- raise "A uniqueness key with args #{@uniqueness_args.inspect} already exists." if @uniqueness_keys && @uniqueness_keys.include?(new_uniqueness_key)
28
- if @similar_service_id = Services.configuration.redis.get(new_uniqueness_key)
29
- case on_error.to_sym
30
- when :fail
31
- raise_non_unique_error
32
- when :reschedule
33
- if error_count >= MAX_RETRIES
34
- raise_non_unique_error
35
- else
36
- increase_error_count
37
- reschedule
38
- end
25
+ @_on_error = on_error
26
+ raise 'Service args not found.' if @_service_args.nil?
27
+ @_uniqueness_args = args.empty? ? @_service_args : args
28
+ new_uniqueness_key = uniqueness_key(@_uniqueness_args)
29
+ raise "A uniqueness key with args #{@_uniqueness_args.inspect} already exists." if @_uniqueness_keys && @_uniqueness_keys.include?(new_uniqueness_key)
30
+ if @_similar_service_id = Services.configuration.redis.get(new_uniqueness_key)
31
+ if on_error.to_sym == :ignore
32
+ return false
33
+ else
34
+ @_retries_exhausted = on_error.to_sym == :reschedule && error_count >= MAX_RETRIES
35
+ raise_not_unique_error
39
36
  end
40
- false
41
37
  else
42
- @uniqueness_keys ||= []
43
- @uniqueness_keys << new_uniqueness_key
38
+ @_uniqueness_keys ||= []
39
+ @_uniqueness_keys << new_uniqueness_key
44
40
  Services.configuration.redis.setex new_uniqueness_key, ONE_HOUR, @id
45
41
  true
46
42
  end
47
43
  end
48
44
 
49
45
  def call(*args)
50
- @service_args = args
46
+ @_service_args = args
51
47
  super
48
+ rescue self.class::NotUniqueError => e
49
+ case @_on_error.to_sym
50
+ when :fail
51
+ raise e
52
+ when :reschedule
53
+ if @_retries_exhausted
54
+ raise e
55
+ else
56
+ increase_error_count
57
+ reschedule
58
+ end
59
+ when :return
60
+ return e
61
+ else
62
+ raise "Unexpected on_error: #{@_on_error}"
63
+ end
52
64
  ensure
53
- Services.configuration.redis.del @uniqueness_keys unless @uniqueness_keys.nil? || @uniqueness_keys.empty?
65
+ Services.configuration.redis.del @_uniqueness_keys unless @_uniqueness_keys.nil? || @_uniqueness_keys.empty?
54
66
  Services.configuration.redis.del error_count_key
55
67
  end
56
68
 
57
69
  private
58
70
 
59
- def raise_non_unique_error(retried = false)
60
- message = "Service #{self.class} #{@id} with uniqueness args #{@uniqueness_args} is not unique, a similar service is already running: #{@similar_service_id}."
61
- message << " The service has been retried #{MAX_RETRIES} times."
62
- raise self.class::NotUniqueError, message
71
+ def raise_not_unique_error
72
+ message = "Service #{self.class} #{@id} with uniqueness args #{@_uniqueness_args} is not unique, a similar service is already running: #{@_similar_service_id}."
73
+ message << " The service has been retried #{MAX_RETRIES} times." if @_retries_exhausted
74
+ raise self.class::NotUniqueError.new(message)
63
75
  end
64
76
 
65
77
  def convert_for_rescheduling(arg)
@@ -79,7 +91,7 @@ module Services
79
91
 
80
92
  def reschedule
81
93
  # Convert service args for rescheduling first
82
- reschedule_args = @service_args.map do |arg|
94
+ reschedule_args = @_service_args.map do |arg|
83
95
  convert_for_rescheduling arg
84
96
  end
85
97
  log "Rescheduling to be executed in #{retry_delay} seconds." if self.respond_to?(:log)
@@ -109,7 +121,7 @@ module Services
109
121
  'errors',
110
122
  self.class.to_s.gsub(':', '_')
111
123
  ].tap do |key|
112
- key << Digest::MD5.hexdigest(@service_args.to_s) unless @service_args.empty?
124
+ key << Digest::MD5.hexdigest(@_service_args.to_s) unless @_service_args.empty?
113
125
  end.join(':')
114
126
  end
115
127
 
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '2.1.0'
2
+ VERSION = '2.2.3'
3
3
  end
@@ -2,52 +2,73 @@ 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
- wait_for_job_to_run_and_finish service, *args, 'fail', true do
5
+ wait_for_job_to_run_and_finish service_class, *args, 'fail', true do
6
6
  # Check that error is raised when on_error is "fail"
7
+ puts 'Checking on_error = fail'
7
8
  if defined?(fail_args)
9
+ puts "* with fail args #{fail_args}"
8
10
  3.times do
9
11
  fail_args.each do |fail_arg_group|
10
- expect { service.call(*fail_arg_group, 'fail', false) }.to raise_error(service::NotUniqueError)
12
+ service = service_class.new
13
+ expect(service).to_not receive(:do_work)
14
+ expect { service.call(*fail_arg_group, 'fail', false) }.to raise_error(service_class::NotUniqueError)
11
15
  end
12
16
  end
13
17
  end
14
18
  if defined?(pass_args)
19
+ puts "* with pass args #{pass_args}"
15
20
  3.times do
16
21
  pass_args.each do |pass_arg_group|
22
+ service = service_class.new
23
+ expect(service).to receive(:do_work)
17
24
  expect { service.call(*pass_arg_group, 'fail', false) }.to_not raise_error
18
25
  end
19
26
  end
20
27
  end
21
28
 
22
29
  # Check that no error is raised when on_error is "ignore"
30
+ puts 'Checking on_error = ignore'
23
31
  if defined?(fail_args)
32
+ puts "* with fail args #{fail_args}"
24
33
  3.times do
25
34
  fail_args.each do |fail_arg_group|
35
+ service = service_class.new
36
+ expect(service).to receive(:do_work)
26
37
  expect { service.call(*fail_arg_group, 'ignore', false) }.to_not raise_error
27
38
  end
28
39
  end
29
40
  end
30
41
  if defined?(pass_args)
42
+ puts "* with pass args #{pass_args}"
31
43
  3.times do
32
44
  pass_args.each do |pass_arg_group|
45
+ service = service_class.new
46
+ expect(service).to receive(:do_work)
33
47
  expect { service.call(*pass_arg_group, 'ignore', false) }.to_not raise_error
34
48
  end
35
49
  end
36
50
  end
37
51
 
38
52
  # Check that service is rescheduled when on_error is "reschedule"
53
+ puts 'Checking on_error = reschedule'
39
54
  if defined?(fail_args)
55
+ puts "* with fail args #{fail_args}"
40
56
  3.times do
41
57
  fail_args.each do |fail_arg_group|
42
- expect(service).to receive(:perform_in).with(an_instance_of(Fixnum), *fail_arg_group, 'reschedule', false)
58
+ service = service_class.new
59
+ expect(service).to_not receive(:do_work)
60
+ expect(service_class).to receive(:perform_in).with(an_instance_of(Fixnum), *fail_arg_group, 'reschedule', false)
43
61
  expect { service.call(*fail_arg_group, 'reschedule', false) }.to_not raise_error
44
62
  end
45
63
  end
46
64
  end
47
65
  if defined?(pass_args)
66
+ puts "* with pass args #{pass_args}"
48
67
  3.times do
49
68
  pass_args.each do |pass_arg_group|
50
- expect(service).to_not receive(:perform_in)
69
+ service = service_class.new
70
+ expect(service).to receive(:do_work)
71
+ expect(service_class).to_not receive(:perform_in)
51
72
  expect { service.call(*pass_arg_group, 'reschedule', false) }.to_not raise_error
52
73
  end
53
74
  end
@@ -63,35 +84,35 @@ end
63
84
  describe Services::Base::UniquenessChecker do
64
85
  context 'when the service checks for uniqueness with the default args' do
65
86
  it_behaves_like 'checking the uniqueness properly' do
66
- let(:service) { UniqueService }
67
- let(:args) { [] }
68
- let(:fail_args) { [] }
87
+ let(:service_class) { UniqueService }
88
+ let(:args) { [] }
89
+ let(:fail_args) { [] }
69
90
  end
70
91
  end
71
92
 
72
93
  context 'when the service checks for uniqueness with custom args' do
73
94
  it_behaves_like 'checking the uniqueness properly' do
74
- let(:service) { UniqueWithCustomArgsService }
75
- let(:args) { ['foo', 1, 'bar'] }
76
- let(:fail_args) { [['foo', 1, 'pelle']] }
77
- let(:pass_args) { [['foo', 2, 'bar']] }
95
+ let(:service_class) { UniqueWithCustomArgsService }
96
+ let(:args) { ['foo', 1, 'bar'] }
97
+ let(:fail_args) { [['foo', 1, 'pelle']] }
98
+ let(:pass_args) { [['foo', 2, 'bar']] }
78
99
  end
79
100
  end
80
101
 
81
102
  context 'when the service checks for uniqueness multiple times' do
82
103
  it_behaves_like 'checking the uniqueness properly' do
83
- let(:service) { UniqueMultipleService }
84
- let(:args) { ['foo', 1, true] }
85
- let(:fail_args) { args.map { |arg| [arg] } }
86
- let(:pass_args) { [%w(pelle)] }
104
+ let(:service_class) { UniqueMultipleService }
105
+ let(:args) { ['foo', 1, true] }
106
+ let(:fail_args) { args.map { |arg| [arg] } }
107
+ let(:pass_args) { [['pelle']] }
87
108
  end
88
109
  end
89
110
 
90
111
  context 'when the service does not check for uniqueness' do
91
112
  it_behaves_like 'checking the uniqueness properly' do
92
- let(:service) { NonUniqueService }
93
- let(:args) { [] }
94
- let(:pass_args) { [] }
113
+ let(:service_class) { NonUniqueService }
114
+ let(:args) { [] }
115
+ let(:pass_args) { [] }
95
116
  end
96
117
  end
97
118
  end
@@ -117,15 +117,19 @@ end
117
117
  class UniqueService < Services::Base
118
118
  def call(on_error, sleep)
119
119
  check_uniqueness on_error: on_error
120
+ do_work
120
121
  sleep 0.5 if sleep
121
122
  end
123
+ def do_work; end
122
124
  end
123
125
 
124
126
  class UniqueWithCustomArgsService < Services::Base
125
127
  def call(uniqueness_arg1, uniqueness_arg2, ignore_arg, on_error, sleep)
126
128
  check_uniqueness uniqueness_arg1, uniqueness_arg2, on_error: on_error
129
+ do_work
127
130
  sleep 0.5 if sleep
128
131
  end
132
+ def do_work; end
129
133
  end
130
134
 
131
135
  class UniqueMultipleService < Services::Base
@@ -133,14 +137,18 @@ class UniqueMultipleService < Services::Base
133
137
  args.each do |arg|
134
138
  check_uniqueness arg, on_error: on_error
135
139
  end
140
+ do_work
136
141
  sleep 0.5 if sleep
137
142
  end
143
+ def do_work; end
138
144
  end
139
145
 
140
146
  class NonUniqueService < Services::Base
141
147
  def call(on_error, sleep)
148
+ do_work
142
149
  sleep 0.5 if sleep
143
150
  end
151
+ def do_work; end
144
152
  end
145
153
 
146
154
  class NestedExceptionService < Services::Base
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: 2.1.0
4
+ version: 2.2.3
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-26 00:00:00.000000000 Z
11
+ date: 2014-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake