services 0.1.7 → 0.2.1

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: 81eb2b7ac07028e41e889899270a9c0144f91443
4
- data.tar.gz: 1464d7a79faba0c979904f3620770c791fbbcca3
3
+ metadata.gz: 5351a6064b1da2a70dd0ce2fba47810bd7deb0f5
4
+ data.tar.gz: d73f3b3835195a720b4c370d15a67a017ca49a2e
5
5
  SHA512:
6
- metadata.gz: 79a292567b259d7bbc5781752da14923376dd005f01cf31eb81a6a7c6fe37d8f978c1a369c4588e622c65a2d329bac1e0f1f52a28e13560864c9061e44289374
7
- data.tar.gz: 6b5f428b5b1acc15a6f35437cbb52bf6c36009ba1866fb8956b308fb130e5466fc77af9ac016e13ba99eb6fb2f68a9b01efeee6e92570a033eb311947b2cee1d
6
+ metadata.gz: cdeb74e291c384e338a04acf1c0036788a84bf87813ff25cae0c19b83d3157cb2b749fb09949f4f14a413fe6e90d6c1045516f86f776c176c45a52bbb147e310
7
+ data.tar.gz: 1ef404e5414c1fb352336b038861884404fac189dece2ce97d2261b81aee00453341e64ad85f1cb256e79e2adffcc0759ca9758de3aa2d1772877a10dd03d23c
data/.gitignore CHANGED
@@ -1,2 +1,2 @@
1
1
  Gemfile.lock
2
- spec/support/logs/**/*.log
2
+ spec/support/log/**/*.log
data/lib/services.rb CHANGED
@@ -18,8 +18,8 @@ begin
18
18
  require_relative 'services/asyncable'
19
19
  rescue Services::BackgroundProcessorNotFound
20
20
  end
21
- require_relative 'services/base/call_logger'
22
- require_relative 'services/base/exception_wrapper'
23
- require_relative 'services/base/uniqueness_checker'
21
+ require_relative 'services/modules/call_logger'
22
+ require_relative 'services/modules/exception_wrapper'
23
+ require_relative 'services/modules/uniqueness_checker'
24
24
  require_relative 'services/base'
25
25
  require_relative 'services/railtie' if defined?(Rails)
data/lib/services/base.rb CHANGED
@@ -9,7 +9,7 @@ module Services
9
9
  subclass.const_set :Error, Class.new(StandardError)
10
10
  subclass.send :include, Rails.application.routes.url_helpers if defined?(Rails)
11
11
  subclass.send :include, Asyncable if defined?(Asyncable)
12
- subclass.send :prepend, CallLogger, UniquenessChecker
12
+ subclass.send :prepend, CallLogger, ExceptionWrapper, UniquenessChecker
13
13
  end
14
14
 
15
15
  delegate :call, to: :new
@@ -8,8 +8,15 @@ module Services
8
8
  result = super
9
9
  rescue StandardError => e
10
10
  log "#{e.class}: #{e.message}"
11
- e.backtrace.each do |line|
12
- log line
11
+ if e.respond_to?(:cause) && !e.cause.nil?
12
+ log "caused by: #{e.cause.class}: #{e.cause.message}"
13
+ e.cause.backtrace.each do |line|
14
+ log line
15
+ end
16
+ else
17
+ e.backtrace.each do |line|
18
+ log line
19
+ end
13
20
  end
14
21
  raise e
15
22
  ensure
File without changes
@@ -0,0 +1,40 @@
1
+ module Services
2
+ class Base
3
+ module UniquenessChecker
4
+ def self.prepended(mod)
5
+ mod.const_set :NotUniqueError, Class.new(mod::Error)
6
+ end
7
+
8
+ 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}"
15
+ else
16
+ Services.configuration.redis.setex @uniqueness_key, 60 * 60, @id
17
+ end
18
+ end
19
+
20
+ def call(*args)
21
+ @uniqueness_all_args = args
22
+ super
23
+ ensure
24
+ Services.configuration.redis.del @uniqueness_key if defined?(@uniqueness_key)
25
+ end
26
+
27
+ private
28
+
29
+ def uniqueness_key(args)
30
+ [
31
+ 'services',
32
+ 'uniqueness',
33
+ self.class.to_s
34
+ ].tap do |key|
35
+ key << Digest::MD5.hexdigest(args.to_s) unless args.empty?
36
+ end.join(':')
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '0.1.7'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -66,30 +66,32 @@ describe Services::Base do
66
66
  end
67
67
 
68
68
  context 'checking for uniqueness' do
69
- context 'when the service was set to check for uniqueness' do
69
+ context 'when the service was set to check for uniqueness with the default args' do
70
70
  it 'raises an error when the same job is executed twice' do
71
71
  wait_for_job_to_run UniqueService.perform_async
72
- expect do
73
- UniqueService.call
74
- end.to raise_error(UniqueService::NotUniqueError)
72
+ expect { UniqueService.call }.to raise_error(UniqueService::NotUniqueError)
73
+ end
74
+ end
75
+
76
+ context 'when the service was set to check for uniqueness with custom args' do
77
+ it 'raises an error when a job with the same custom args is executed twice' do
78
+ wait_for_job_to_run UniqueWithCustomArgsService.perform_async('foo', 'bar', 'baz')
79
+ expect { UniqueWithCustomArgsService.call('foo', 'bar', 'pelle') }.to raise_error(UniqueWithCustomArgsService::NotUniqueError)
80
+ expect { UniqueWithCustomArgsService.call('foo', 'baz', 'pelle') }.to_not raise_error
75
81
  end
76
82
  end
77
83
 
78
84
  context 'when the service was not set to check for uniqueness' do
79
85
  it 'does not raise an error when the same job is executed twice' do
80
86
  wait_for_job_to_run NonUniqueService.perform_async
81
- expect do
82
- NonUniqueService.call
83
- end.to_not raise_error
87
+ expect { NonUniqueService.call }.to_not raise_error
84
88
  end
85
89
  end
86
90
  end
87
91
 
88
92
  context 'when executed asynchronously' do
89
93
  it 'finds its own worker' do
90
- 3.times do
91
- OwnWorkerService.perform_async
92
- end
94
+ 3.times { OwnWorkerService.perform_async }
93
95
  jid = OwnWorkerService.perform_async
94
96
  own_worker_data = wait_for { Services.configuration.redis.get(jid) }
95
97
  own_worker_json = JSON.parse(own_worker_data)
@@ -97,16 +99,12 @@ describe Services::Base do
97
99
  end
98
100
 
99
101
  it 'finds its sibling workers' do
100
- sibling_worker_jids = (1..3).map do
101
- SiblingWorkersService.perform_async
102
- end
102
+ sibling_worker_jids = (1..3).map { SiblingWorkersService.perform_async }
103
103
  jid = SiblingWorkersService.perform_async
104
104
  sibling_worker_data = wait_for { Services.configuration.redis.get(jid) }
105
105
  sibling_worker_json = JSON.parse(sibling_worker_data)
106
106
  expect(sibling_worker_json.size).to eq(3)
107
- expected_sibling_worker_jids = sibling_worker_json.map do |_, _, work|
108
- work['payload']['jid']
109
- end
107
+ expected_sibling_worker_jids = sibling_worker_json.map { |_, _, work| work['payload']['jid'] }
110
108
  expect(expected_sibling_worker_jids).to match_array(sibling_worker_jids)
111
109
  end
112
110
  end
data/spec/spec_helper.rb CHANGED
@@ -7,7 +7,7 @@ require_relative 'support/test_services'
7
7
  require_relative 'support/helpers'
8
8
 
9
9
  support_dir = Pathname.new(File.expand_path('../support', __FILE__))
10
- log_dir = support_dir.join('logs')
10
+ log_dir = support_dir.join('log')
11
11
 
12
12
  redis_port = 6379
13
13
  redis_pidfile = support_dir.join('redis.pid')
File without changes
@@ -1,7 +1,13 @@
1
1
  class UniqueService < Services::Base
2
- check_uniqueness!
3
-
4
2
  def call
3
+ check_uniqueness!
4
+ sleep 0.5
5
+ end
6
+ end
7
+
8
+ class UniqueWithCustomArgsService < Services::Base
9
+ def call(uniqueness_arg1, uniqueness_arg2, ignore_arg)
10
+ check_uniqueness! uniqueness_arg1, uniqueness_arg2
5
11
  sleep 0.5
6
12
  end
7
13
  end
metadata CHANGED
@@ -1,125 +1,125 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: services
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.1
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-07-11 00:00:00.000000000 Z
11
+ date: 2014-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: guard-rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '4.2'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sidekiq
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: redis
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: tries
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.3'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rails
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: 3.0.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 3.0.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: gem_config
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ~>
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0.3'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ~>
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.3'
125
125
  description: ''
@@ -128,8 +128,8 @@ executables: []
128
128
  extensions: []
129
129
  extra_rdoc_files: []
130
130
  files:
131
- - .gitignore
132
- - .travis.yml
131
+ - ".gitignore"
132
+ - ".travis.yml"
133
133
  - Gemfile
134
134
  - Guardfile
135
135
  - LICENSE.txt
@@ -138,17 +138,17 @@ files:
138
138
  - lib/services.rb
139
139
  - lib/services/asyncable.rb
140
140
  - lib/services/base.rb
141
- - lib/services/base/call_logger.rb
142
- - lib/services/base/exception_wrapper.rb
143
- - lib/services/base/uniqueness_checker.rb
144
141
  - lib/services/logger.rb
142
+ - lib/services/modules/call_logger.rb
143
+ - lib/services/modules/exception_wrapper.rb
144
+ - lib/services/modules/uniqueness_checker.rb
145
145
  - lib/services/railtie.rb
146
146
  - lib/services/version.rb
147
147
  - services.gemspec
148
148
  - spec/services/base_spec.rb
149
149
  - spec/spec_helper.rb
150
150
  - spec/support/helpers.rb
151
- - spec/support/logs/.gitkeep
151
+ - spec/support/log/.gitkeep
152
152
  - spec/support/redis-cli
153
153
  - spec/support/redis-server
154
154
  - spec/support/test_services.rb
@@ -162,12 +162,12 @@ require_paths:
162
162
  - lib
163
163
  required_ruby_version: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - '>='
165
+ - - ">="
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0'
168
168
  required_rubygems_version: !ruby/object:Gem::Requirement
169
169
  requirements:
170
- - - '>='
170
+ - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
173
  requirements: []
@@ -180,7 +180,7 @@ test_files:
180
180
  - spec/services/base_spec.rb
181
181
  - spec/spec_helper.rb
182
182
  - spec/support/helpers.rb
183
- - spec/support/logs/.gitkeep
183
+ - spec/support/log/.gitkeep
184
184
  - spec/support/redis-cli
185
185
  - spec/support/redis-server
186
186
  - spec/support/test_services.rb
@@ -1,49 +0,0 @@
1
- module Services
2
- class Base
3
- module UniquenessChecker
4
- def self.prepended(mod)
5
- mod.instance_eval do
6
- def check_uniqueness?
7
- @check_uniqueness
8
- end
9
-
10
- def check_uniqueness!
11
- @check_uniqueness = true
12
- end
13
- end
14
- mod.const_set :NotUniqueError, Class.new(mod::Error)
15
- end
16
-
17
- def call(*args)
18
- if self.class.check_uniqueness?
19
- key = unique_key(args)
20
- if Services.configuration.redis.exists(key)
21
- raise self.class::NotUniqueError
22
- else
23
- Services.configuration.redis.setex key, 60 * 60, Time.now
24
- begin
25
- super
26
- ensure
27
- Services.configuration.redis.del key
28
- end
29
- end
30
- else
31
- super
32
- end
33
- end
34
-
35
- private
36
-
37
- def unique_key(args)
38
- # TODO: symbolize keys in hashes in args and sort hashes by key
39
- args = args.dup
40
- key = [
41
- 'services',
42
- 'uniqueness',
43
- self.class.to_s,
44
- Digest::MD5.hexdigest(args.to_s)
45
- ].join(':')
46
- end
47
- end
48
- end
49
- end