services 2.1.0 → 2.2.3

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 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