services 0.1.2 → 0.1.7

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: c148465c5f9136b280c87824fb53878b9e17e05d
4
- data.tar.gz: 3fd963a4ec9b77e26a2cd2c0bacfe9e1f7924ecd
3
+ metadata.gz: 81eb2b7ac07028e41e889899270a9c0144f91443
4
+ data.tar.gz: 1464d7a79faba0c979904f3620770c791fbbcca3
5
5
  SHA512:
6
- metadata.gz: d963a730efde270e4137e45f08465a127f27a15581a4c8cc26401ae1b0101bc19737097200502b57004b73fc4b4e8fce3a5b4b15e0347d88e1bab339155ee3f0
7
- data.tar.gz: 23fc5b5174f0ecf0ec261b35fcb886f67907a506f755fc7fb13c10a93f74aede3eec0005eca608ef0e7fada73342a02ae08f9bc44825aa630d789ee7a90ad0ac
6
+ metadata.gz: 79a292567b259d7bbc5781752da14923376dd005f01cf31eb81a6a7c6fe37d8f978c1a369c4588e622c65a2d329bac1e0f1f52a28e13560864c9061e44289374
7
+ data.tar.gz: 6b5f428b5b1acc15a6f35437cbb52bf6c36009ba1866fb8956b308fb130e5466fc77af9ac016e13ba99eb6fb2f68a9b01efeee6e92570a033eb311947b2cee1d
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
3
+ - 2.0
4
4
  - 2.1
5
5
  services:
6
6
  - redis-server
@@ -2,6 +2,7 @@ require 'active_support/concern'
2
2
 
3
3
  begin
4
4
  require 'sidekiq'
5
+ require 'sidekiq/api'
5
6
  rescue LoadError
6
7
  raise Services::BackgroundProcessorNotFound
7
8
  end
@@ -58,17 +59,17 @@ module Services
58
59
  @own_worker = if self.jid.nil?
59
60
  nil
60
61
  else
61
- own_worker = Sidekiq::Workers.new.detect do |_, work, _|
62
+ own_worker = Sidekiq::Workers.new.detect do |_, _, work|
62
63
  work['payload']['jid'] == self.jid
63
64
  end
64
- raise self.class::Error, "Could not find own worker with jid #{self.jid}: #{Sidekiq::Workers.new.map{ |*args| args }}" if own_worker.nil?
65
+ raise self.class::Error, "Could not find own worker with jid #{self.jid}: #{Sidekiq::Workers.new.map { |*args| args }}" if own_worker.nil?
65
66
  own_worker
66
67
  end
67
68
  end
68
69
 
69
70
  def sibling_workers
70
- @sibling_workers ||= Sidekiq::Workers.new.select do |_, work, _|
71
- work['payload']['class'] == self.class.to_s && (own_worker.nil? || work['payload']['jid'] != own_worker[1]['payload']['jid'])
71
+ @sibling_workers ||= Sidekiq::Workers.new.select do |_, _, work|
72
+ work['payload']['class'] == self.class.to_s && (own_worker.nil? || work['payload']['jid'] != own_worker[2]['payload']['jid'])
72
73
  end
73
74
  end
74
75
  end
@@ -1,4 +1,3 @@
1
- require 'nesty'
2
1
  require 'securerandom'
3
2
  require 'action_dispatch'
4
3
  require 'digest'
@@ -7,10 +6,10 @@ module Services
7
6
  class Base
8
7
  class << self
9
8
  def inherited(subclass)
10
- subclass.const_set :Error, Class.new(Nesty::NestedStandardError)
9
+ subclass.const_set :Error, Class.new(StandardError)
11
10
  subclass.send :include, Rails.application.routes.url_helpers if defined?(Rails)
12
11
  subclass.send :include, Asyncable if defined?(Asyncable)
13
- subclass.send :prepend, CallLogger, ExceptionWrapper, UniquenessChecker
12
+ subclass.send :prepend, CallLogger, UniquenessChecker
14
13
  end
15
14
 
16
15
  delegate :call, to: :new
@@ -1,3 +1,3 @@
1
1
  module Services
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.7'
3
3
  end
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
13
13
  gem.email = 'manuel@krautcomputing.com'
14
14
  gem.summary = ''
15
15
  gem.description = ''
16
- gem.homepage = ''
16
+ gem.homepage = 'http://krautcomputing.github.io/services'
17
17
  gem.license = 'MIT'
18
18
 
19
19
  gem.files = `git ls-files`.split($/)
@@ -23,10 +23,10 @@ Gem::Specification.new do |gem|
23
23
 
24
24
  gem.add_development_dependency 'rake'
25
25
  gem.add_development_dependency 'guard-rspec', '~> 4.2'
26
- gem.add_development_dependency 'rspec', '>= 3.0.0.rc1', '< 4'
26
+ gem.add_development_dependency 'rspec', '~> 3.0'
27
27
  gem.add_development_dependency 'sidekiq', '~> 3.0'
28
28
  gem.add_development_dependency 'redis', '~> 3.0'
29
+ gem.add_development_dependency 'tries', '~> 0.3'
29
30
  gem.add_runtime_dependency 'rails', '>= 3.0.0'
30
- gem.add_runtime_dependency 'gem_config', '~> 0.3.1'
31
- gem.add_runtime_dependency 'nesty', '~> 1.0.2'
31
+ gem.add_runtime_dependency 'gem_config', '~> 0.3'
32
32
  end
@@ -1,64 +1,66 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Services::Base do
4
- context 'wrapping exceptions' do
5
- it 'does not wrap service errors or subclasses' do
6
- class ServiceWithError < Services::Base
7
- def call
8
- raise Error.new('I am a service error.', nil)
4
+ class ServiceWithError < Services::Base
5
+ def call
6
+ raise Error.new('I am a service error.')
7
+ end
8
+ end
9
+ if ServiceWithError::Error.new.respond_to?(:cause)
10
+ context 'wrapping exceptions' do
11
+ it 'does not wrap service errors or subclasses' do
12
+ expect do
13
+ ServiceWithError.call
14
+ end.to raise_error do |error|
15
+ expect(error).to be_a(ServiceWithError::Error)
16
+ expect(error.message).to eq('I am a service error.')
17
+ expect(error.cause).to be_nil
9
18
  end
10
- end
11
- expect do
12
- ServiceWithError.call
13
- end.to raise_error do |error|
14
- expect(error).to be_a(ServiceWithError::Error)
15
- expect(error.message).to eq('I am a service error.')
16
- expect(error.nested).to be_nil
17
- end
18
19
 
19
- class ServiceWithCustomError < Services::Base
20
- CustomError = Class.new(self::Error)
21
- def call
22
- raise CustomError.new('I am a custom error.', nil)
20
+ class ServiceWithCustomError < Services::Base
21
+ CustomError = Class.new(self::Error)
22
+ def call
23
+ raise CustomError.new('I am a custom error.')
24
+ end
25
+ end
26
+ expect do
27
+ ServiceWithCustomError.call
28
+ end.to raise_error do |error|
29
+ expect(error).to be_a(ServiceWithCustomError::CustomError)
30
+ expect(error.message).to eq('I am a custom error.')
31
+ expect(error.cause).to be_nil
23
32
  end
24
33
  end
25
- expect do
26
- ServiceWithCustomError.call
27
- end.to raise_error do |error|
28
- expect(error).to be_a(ServiceWithCustomError::CustomError)
29
- expect(error.message).to eq('I am a custom error.')
30
- expect(error.nested).to be_nil
31
- end
32
- end
33
34
 
34
- it 'wraps all other exceptions' do
35
- class ServiceWithStandardError < Services::Base
36
- def call
37
- raise 'I am a StandardError.'
35
+ it 'wraps all other exceptions' do
36
+ class ServiceWithStandardError < Services::Base
37
+ def call
38
+ raise 'I am a StandardError.'
39
+ end
40
+ end
41
+ expect do
42
+ ServiceWithStandardError.call
43
+ end.to raise_error do |error|
44
+ expect(error).to be_a(ServiceWithStandardError::Error)
45
+ expect(error.message).to eq('I am a StandardError.')
46
+ expect(error.cause).to be_a(StandardError)
47
+ expect(error.cause.message).to eq('I am a StandardError.')
38
48
  end
39
- end
40
- expect do
41
- ServiceWithStandardError.call
42
- end.to raise_error do |error|
43
- expect(error).to be_a(ServiceWithStandardError::Error)
44
- expect(error.message).to eq('I am a StandardError.')
45
- expect(error.nested).to be_a(StandardError)
46
- expect(error.nested.message).to eq('I am a StandardError.')
47
- end
48
49
 
49
- class ServiceWithCustomStandardError < Services::Base
50
- CustomStandardError = Class.new(StandardError)
51
- def call
52
- raise CustomStandardError, 'I am a custom StandardError.'
50
+ class ServiceWithCustomStandardError < Services::Base
51
+ CustomStandardError = Class.new(StandardError)
52
+ def call
53
+ raise CustomStandardError, 'I am a custom StandardError.'
54
+ end
55
+ end
56
+ expect do
57
+ ServiceWithCustomStandardError.call
58
+ end.to raise_error do |error|
59
+ expect(error).to be_a(ServiceWithCustomStandardError::Error)
60
+ expect(error.message).to eq('I am a custom StandardError.')
61
+ expect(error.cause).to be_a(ServiceWithCustomStandardError::CustomStandardError)
62
+ expect(error.cause.message).to eq('I am a custom StandardError.')
53
63
  end
54
- end
55
- expect do
56
- ServiceWithCustomStandardError.call
57
- end.to raise_error do |error|
58
- expect(error).to be_a(ServiceWithCustomStandardError::Error)
59
- expect(error.message).to eq('I am a custom StandardError.')
60
- expect(error.nested).to be_a(ServiceWithCustomStandardError::CustomStandardError)
61
- expect(error.nested.message).to eq('I am a custom StandardError.')
62
64
  end
63
65
  end
64
66
  end
@@ -66,8 +68,7 @@ describe Services::Base do
66
68
  context 'checking for uniqueness' do
67
69
  context 'when the service was set to check for uniqueness' do
68
70
  it 'raises an error when the same job is executed twice' do
69
- UniqueService.perform_async
70
- sleep 0.5 # Wait for Sidekiq to start processing the job
71
+ wait_for_job_to_run UniqueService.perform_async
71
72
  expect do
72
73
  UniqueService.call
73
74
  end.to raise_error(UniqueService::NotUniqueError)
@@ -76,12 +77,37 @@ describe Services::Base do
76
77
 
77
78
  context 'when the service was not set to check for uniqueness' do
78
79
  it 'does not raise an error when the same job is executed twice' do
79
- NonUniqueService.perform_async
80
- sleep 0.5 # Wait for Sidekiq to start processing the job
80
+ wait_for_job_to_run NonUniqueService.perform_async
81
81
  expect do
82
82
  NonUniqueService.call
83
83
  end.to_not raise_error
84
84
  end
85
85
  end
86
86
  end
87
+
88
+ context 'when executed asynchronously' do
89
+ it 'finds its own worker' do
90
+ 3.times do
91
+ OwnWorkerService.perform_async
92
+ end
93
+ jid = OwnWorkerService.perform_async
94
+ own_worker_data = wait_for { Services.configuration.redis.get(jid) }
95
+ own_worker_json = JSON.parse(own_worker_data)
96
+ expect(own_worker_json[2]['payload']['jid']).to eq(jid)
97
+ end
98
+
99
+ it 'finds its sibling workers' do
100
+ sibling_worker_jids = (1..3).map do
101
+ SiblingWorkersService.perform_async
102
+ end
103
+ jid = SiblingWorkersService.perform_async
104
+ sibling_worker_data = wait_for { Services.configuration.redis.get(jid) }
105
+ sibling_worker_json = JSON.parse(sibling_worker_data)
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
110
+ expect(expected_sibling_worker_jids).to match_array(sibling_worker_jids)
111
+ end
112
+ end
87
113
  end
@@ -1,8 +1,10 @@
1
1
  require 'rspec'
2
+ require 'tries'
2
3
  require 'redis'
3
4
  require 'sidekiq'
4
5
  require_relative '../lib/services'
5
6
  require_relative 'support/test_services'
7
+ require_relative 'support/helpers'
6
8
 
7
9
  support_dir = Pathname.new(File.expand_path('../support', __FILE__))
8
10
  log_dir = support_dir.join('logs')
@@ -12,7 +14,7 @@ redis_pidfile = support_dir.join('redis.pid')
12
14
  redis_url = "redis://localhost:#{redis_port}/0"
13
15
 
14
16
  sidekiq_pidfile = support_dir.join('sidekiq.pid')
15
- sidekiq_timeout = 60
17
+ sidekiq_timeout = 20
16
18
 
17
19
  Services.configure do |config|
18
20
  config.redis = Redis.new
@@ -44,11 +46,11 @@ RSpec.configure do |config|
44
46
  }
45
47
  redis = support_dir.join('redis-server')
46
48
  # TODO: Redis should be started here unless Rspec is executed by Travis CI
47
- # system "#{redis} #{options_hash_to_string(redis_options)}"
49
+ system "#{redis} #{options_hash_to_string(redis_options)}"
48
50
 
49
51
  # Start Sidekiq
50
52
  sidekiq_options = {
51
- concurrency: 1,
53
+ concurrency: 10,
52
54
  daemon: true,
53
55
  timeout: sidekiq_timeout,
54
56
  verbose: true,
@@ -70,11 +72,11 @@ RSpec.configure do |config|
70
72
  # Stop Redis
71
73
  redis_cli = support_dir.join('redis-cli')
72
74
  # TODO: Redis should be stopped here unless Rspec is executed by Travis CI
73
- # system "#{redis_cli} -p #{redis_port} shutdown"
74
- # while File.exist?(redis_pidfile)
75
- # puts 'Waiting for Redis to shut down...'
76
- # sleep 1
77
- # end
75
+ system "#{redis_cli} -p #{redis_port} shutdown"
76
+ while File.exist?(redis_pidfile)
77
+ puts 'Waiting for Redis to shut down...'
78
+ sleep 1
79
+ end
78
80
 
79
81
  # Truncate log files
80
82
  max_len = 1024 * 1024 # 1 MB
@@ -0,0 +1,17 @@
1
+ require 'sidekiq/api'
2
+
3
+ ExpectedDataNotFoundError = Class.new(StandardError)
4
+
5
+ def wait_for(&block)
6
+ 10.tries on: ExpectedDataNotFoundError, delay: 0.1 do
7
+ block.call or raise ExpectedDataNotFoundError
8
+ end
9
+ end
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
16
+ end
17
+ end
@@ -2,12 +2,34 @@ class UniqueService < Services::Base
2
2
  check_uniqueness!
3
3
 
4
4
  def call
5
- sleep 1
5
+ sleep 0.5
6
6
  end
7
7
  end
8
8
 
9
9
  class NonUniqueService < Services::Base
10
10
  def call
11
- sleep 1
11
+ sleep 0.5
12
+ end
13
+ end
14
+
15
+ class OwnWorkerService < Services::Base
16
+ def call
17
+ if own_worker.nil?
18
+ logger.error 'Could not find own worker!'
19
+ else
20
+ Services.configuration.redis.set self.jid, own_worker.to_json
21
+ end
22
+ sleep 0.5
23
+ end
24
+ end
25
+
26
+ class SiblingWorkersService < Services::Base
27
+ def call
28
+ if sibling_workers.empty?
29
+ logger.info 'No sibling workers found.'
30
+ else
31
+ Services.configuration.redis.set self.jid, sibling_workers.to_json
32
+ end
33
+ sleep 0.5
12
34
  end
13
35
  end
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.1.2
4
+ version: 0.1.7
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-05-27 00:00:00.000000000 Z
11
+ date: 2014-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -42,22 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: 3.0.0.rc1
48
- - - <
45
+ - - ~>
49
46
  - !ruby/object:Gem::Version
50
- version: '4'
47
+ version: '3.0'
51
48
  type: :development
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
- - - '>='
56
- - !ruby/object:Gem::Version
57
- version: 3.0.0.rc1
58
- - - <
52
+ - - ~>
59
53
  - !ruby/object:Gem::Version
60
- version: '4'
54
+ version: '3.0'
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: sidekiq
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -87,47 +81,47 @@ dependencies:
87
81
  - !ruby/object:Gem::Version
88
82
  version: '3.0'
89
83
  - !ruby/object:Gem::Dependency
90
- name: rails
84
+ name: tries
91
85
  requirement: !ruby/object:Gem::Requirement
92
86
  requirements:
93
- - - '>='
87
+ - - ~>
94
88
  - !ruby/object:Gem::Version
95
- version: 3.0.0
96
- type: :runtime
89
+ version: '0.3'
90
+ type: :development
97
91
  prerelease: false
98
92
  version_requirements: !ruby/object:Gem::Requirement
99
93
  requirements:
100
- - - '>='
94
+ - - ~>
101
95
  - !ruby/object:Gem::Version
102
- version: 3.0.0
96
+ version: '0.3'
103
97
  - !ruby/object:Gem::Dependency
104
- name: gem_config
98
+ name: rails
105
99
  requirement: !ruby/object:Gem::Requirement
106
100
  requirements:
107
- - - ~>
101
+ - - '>='
108
102
  - !ruby/object:Gem::Version
109
- version: 0.3.1
103
+ version: 3.0.0
110
104
  type: :runtime
111
105
  prerelease: false
112
106
  version_requirements: !ruby/object:Gem::Requirement
113
107
  requirements:
114
- - - ~>
108
+ - - '>='
115
109
  - !ruby/object:Gem::Version
116
- version: 0.3.1
110
+ version: 3.0.0
117
111
  - !ruby/object:Gem::Dependency
118
- name: nesty
112
+ name: gem_config
119
113
  requirement: !ruby/object:Gem::Requirement
120
114
  requirements:
121
115
  - - ~>
122
116
  - !ruby/object:Gem::Version
123
- version: 1.0.2
117
+ version: '0.3'
124
118
  type: :runtime
125
119
  prerelease: false
126
120
  version_requirements: !ruby/object:Gem::Requirement
127
121
  requirements:
128
122
  - - ~>
129
123
  - !ruby/object:Gem::Version
130
- version: 1.0.2
124
+ version: '0.3'
131
125
  description: ''
132
126
  email: manuel@krautcomputing.com
133
127
  executables: []
@@ -153,11 +147,12 @@ files:
153
147
  - services.gemspec
154
148
  - spec/services/base_spec.rb
155
149
  - spec/spec_helper.rb
150
+ - spec/support/helpers.rb
156
151
  - spec/support/logs/.gitkeep
157
152
  - spec/support/redis-cli
158
153
  - spec/support/redis-server
159
154
  - spec/support/test_services.rb
160
- homepage: ''
155
+ homepage: http://krautcomputing.github.io/services
161
156
  licenses:
162
157
  - MIT
163
158
  metadata: {}
@@ -184,6 +179,7 @@ summary: ''
184
179
  test_files:
185
180
  - spec/services/base_spec.rb
186
181
  - spec/spec_helper.rb
182
+ - spec/support/helpers.rb
187
183
  - spec/support/logs/.gitkeep
188
184
  - spec/support/redis-cli
189
185
  - spec/support/redis-server