umbra-rb 0.2.0 → 0.3.0.pre

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
  SHA256:
3
- metadata.gz: 12773099d5e69ca31d44d8751335f2dd7652c3d37626be3f7e69ba1048f2d8eb
4
- data.tar.gz: 7d29a4d0c0bf0e7c715a88e8696e99b9c92e2eb590738edab34b62e334e900e6
3
+ metadata.gz: b78a47b9846524b89aa167c590d5f912fec5b15e3f257f131bec39717469cbc5
4
+ data.tar.gz: '0638dcec00b31af9ef1acb84969fef4dcab5cab1ad24453e52fea11491275655'
5
5
  SHA512:
6
- metadata.gz: e7ba308273cf8ab2d97d12081e03449b220972b1f9759613f99507b956f29c6538ff3aa11c9e5fbced6326878fbb096393ab95fa2659c0b3410b835a94f2966d
7
- data.tar.gz: a3e54eb44ff862456c5d474e38fd5058f358e5a36264bd65aaffed18861baa456a65259d890b069e40554d2bda7515e9d412e94d62d048b48671f2a1487cf0f6
6
+ metadata.gz: 38b6958b37872340e07ae3e0f0f18371ae2a7e27787a2521fe9eda8962f8f5e1c7355177677650e811b2e5ba5b1fefb2e228a56993c3a774147191e1df289fe8
7
+ data.tar.gz: 6255267c65a90494b301367ccd14645a3e4dc8c481115155fd6c60e94ce1f4ad64d4125b13de2b48d83e84132da1df3a2602689ff35a213f25df2c1dcea30566
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- umbra-rb (0.2.0)
4
+ umbra-rb (0.3.0.pre)
5
+ concurrent-ruby (~> 1.1)
5
6
  multi_json (~> 1.13)
6
7
  oj (~> 3.9)
7
8
  redis (~> 4.1)
@@ -10,57 +11,70 @@ PATH
10
11
  GEM
11
12
  remote: https://rubygems.org/
12
13
  specs:
14
+ addressable (2.7.0)
15
+ public_suffix (>= 2.0.2, < 5.0)
13
16
  ast (2.4.0)
14
- carwow_rubocop (3.0.3)
15
- rubocop (>= 0.68)
17
+ carwow_rubocop (3.2.1)
18
+ rubocop (>= 0.78)
16
19
  rubocop-performance
17
20
  rubocop-rspec
18
21
  coderay (1.1.2)
22
+ concurrent-ruby (1.1.5)
23
+ crack (0.4.3)
24
+ safe_yaml (~> 1.0.0)
19
25
  diff-lcs (1.3)
20
26
  ethon (0.12.0)
21
27
  ffi (>= 1.3.0)
22
- ffi (1.11.1)
23
- jaro_winkler (1.5.3)
28
+ ffi (1.12.1)
29
+ hashdiff (1.0.0)
30
+ jaro_winkler (1.5.4)
24
31
  method_source (0.9.2)
25
- multi_json (1.13.1)
26
- oj (3.9.2)
27
- parallel (1.17.0)
28
- parser (2.6.4.1)
32
+ multi_json (1.14.1)
33
+ oj (3.10.1)
34
+ parallel (1.19.1)
35
+ parser (2.7.0.2)
29
36
  ast (~> 2.4.0)
30
37
  pry (0.12.2)
31
38
  coderay (~> 1.1.0)
32
39
  method_source (~> 0.9.0)
40
+ public_suffix (4.0.3)
41
+ rack (2.1.1)
33
42
  rainbow (3.0.0)
34
- rake (10.5.0)
43
+ rake (13.0.1)
35
44
  redis (4.1.3)
36
- rspec (3.8.0)
37
- rspec-core (~> 3.8.0)
38
- rspec-expectations (~> 3.8.0)
39
- rspec-mocks (~> 3.8.0)
40
- rspec-core (3.8.2)
41
- rspec-support (~> 3.8.0)
42
- rspec-expectations (3.8.4)
45
+ rspec (3.9.0)
46
+ rspec-core (~> 3.9.0)
47
+ rspec-expectations (~> 3.9.0)
48
+ rspec-mocks (~> 3.9.0)
49
+ rspec-core (3.9.0)
50
+ rspec-support (~> 3.9.0)
51
+ rspec-expectations (3.9.0)
43
52
  diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.8.0)
45
- rspec-mocks (3.8.1)
53
+ rspec-support (~> 3.9.0)
54
+ rspec-mocks (3.9.0)
46
55
  diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.8.0)
48
- rspec-support (3.8.2)
49
- rubocop (0.74.0)
56
+ rspec-support (~> 3.9.0)
57
+ rspec-support (3.9.0)
58
+ rubocop (0.79.0)
50
59
  jaro_winkler (~> 1.5.1)
51
60
  parallel (~> 1.10)
52
- parser (>= 2.6)
61
+ parser (>= 2.7.0.1)
53
62
  rainbow (>= 2.2.2, < 4.0)
54
63
  ruby-progressbar (~> 1.7)
55
64
  unicode-display_width (>= 1.4.0, < 1.7)
56
- rubocop-performance (1.4.1)
65
+ rubocop-performance (1.5.2)
57
66
  rubocop (>= 0.71.0)
58
- rubocop-rspec (1.35.0)
59
- rubocop (>= 0.60.0)
67
+ rubocop-rspec (1.37.1)
68
+ rubocop (>= 0.68.1)
60
69
  ruby-progressbar (1.10.1)
70
+ safe_yaml (1.0.5)
61
71
  typhoeus (1.3.1)
62
72
  ethon (>= 0.9.0)
63
73
  unicode-display_width (1.6.0)
74
+ webmock (3.8.0)
75
+ addressable (>= 2.3.6)
76
+ crack (>= 0.3.2)
77
+ hashdiff (>= 0.4.0, < 2.0.0)
64
78
 
65
79
  PLATFORMS
66
80
  ruby
@@ -69,9 +83,11 @@ DEPENDENCIES
69
83
  bundler (~> 2.0)
70
84
  carwow_rubocop
71
85
  pry
72
- rake (~> 10.0)
86
+ rack
87
+ rake (~> 13.0)
73
88
  rspec (~> 3.0)
74
89
  umbra-rb!
90
+ webmock (~> 3)
75
91
 
76
92
  BUNDLED WITH
77
93
  2.0.2
data/config.ru ADDED
@@ -0,0 +1,8 @@
1
+ require 'rack'
2
+ require 'rack/lobster'
3
+ require 'umbra'
4
+
5
+ Umbra.configure
6
+
7
+ use Umbra::Middleware
8
+ run Rack::Lobster.new
data/lib/umbra.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'typhoeus'
4
4
  require 'redis'
5
5
  require 'multi_json'
6
+ require 'concurrent'
6
7
 
7
8
  module Umbra
8
9
  autoload :Config, 'umbra/config'
data/lib/umbra/config.rb CHANGED
@@ -4,7 +4,7 @@ module Umbra
4
4
 
5
5
  def self.default(&block)
6
6
  new(
7
- publisher: Publisher,
7
+ publisher: Publisher.new,
8
8
  request_selector: RequestSelector,
9
9
  encoder: Encoder,
10
10
  error_handler: SuppressErrorHandler,
@@ -1,55 +1,30 @@
1
1
  module Umbra
2
- class Publisher < SynchronousPublisher
3
- MAX_QUEUE_SIZE = 100
4
-
5
- class << self
6
- def call(env, response)
7
- start_once!
8
-
9
- if @queue.size > MAX_QUEUE_SIZE
10
- Umbra.logger.warn '[umbra] Publish queue at max - dropping items'
11
- return
12
- end
13
-
14
- @queue.push(proc { super(env, response) })
15
- end
16
-
17
- private
18
-
19
- # rubocop:disable Metrics/MethodLength
20
- def start_once!
21
- LOCK.synchronize do
22
- return if @started == Process.pid
23
-
24
- Umbra.logger.info '[umbra] Starting publishing thread'
25
-
26
- @started = Process.pid
27
- @queue = Queue.new
2
+ class Publisher
3
+ DEFAULT_MAX_QUEUE = 100
4
+ DEFAULT_MIN_THREADS = 1
5
+ DEFAULT_MAX_THREADS = 1
6
+
7
+ def initialize(**options)
8
+ @pool = Concurrent::CachedThreadPool.new(
9
+ min_threads: options.fetch(:min_threads, DEFAULT_MIN_THREADS),
10
+ max_threads: options.fetch(:max_thread, DEFAULT_MAX_THREADS),
11
+ max_queue: options.fetch(:max_queue, DEFAULT_MAX_QUEUE),
12
+ fallback_policy: :abort
13
+ )
14
+ end
28
15
 
29
- worker_thread = Thread.new do
30
- while (x = @queue.pop)
31
- break if x == STOP
16
+ def call(env, response, encoder: Umbra.encoder, redis: Umbra.redis)
17
+ @pool << proc { call!(env, response, encoder: encoder, redis: redis) }
32
18
 
33
- begin
34
- x.call
35
- rescue StandardError => e
36
- Umbra.logger.warn '[umbra] Error in publishing thread'
37
- Umbra.config.error_handler.call(e)
38
- end
39
- end
40
- end
19
+ true
20
+ rescue Concurrent::RejectedExecutionError
21
+ Umbra.logger.warn '[umbra] Queue at max - dropping items'
41
22
 
42
- at_exit do
43
- @queue.push(STOP)
44
- worker_thread.join
45
- end
46
- end
47
- end
48
- # rubocop:enable Metrics/MethodLength
23
+ false
49
24
  end
50
25
 
51
- STOP = Object.new
52
- LOCK = Mutex.new
53
- private_constant :STOP, :LOCK
26
+ def call!(env, response, encoder: Umbra.encoder, redis: Umbra.redis)
27
+ redis.publish(Umbra::CHANNEL, encoder.call(env, response))
28
+ end
54
29
  end
55
30
  end
@@ -21,9 +21,9 @@ module Umbra
21
21
 
22
22
  def headers(env)
23
23
  request(env)
24
- .fetch('headers')
25
- .merge(UMBRA_HEADERS)
26
- .transform_keys { |key| key.split('_').drop(1).map(&:capitalize).join('-') }
24
+ .fetch('headers')
25
+ .merge(UMBRA_HEADERS)
26
+ .transform_keys { |key| key.split('_').drop(1).map(&:capitalize).join('-') }
27
27
  end
28
28
 
29
29
  def method(env)
@@ -1,60 +1,34 @@
1
1
  module Umbra
2
2
  class ShadowRequester
3
+ attr_reader :queue, :count
4
+
3
5
  def initialize(count: 1, pool: 1, max_queue_size: 100)
4
6
  @count = count
5
- @pool = pool
6
- @queue = Queue.new
7
- @stop = Object.new
8
- @lock = Mutex.new
9
- @max_queue_size = max_queue_size
7
+ @queue ||= Concurrent::CachedThreadPool.new(
8
+ min_threads: 1,
9
+ max_threads: pool,
10
+ max_queue: max_queue_size,
11
+ fallback_policy: :abort
12
+ )
10
13
  end
11
14
 
12
15
  def call(env)
13
- start_worker!
14
-
15
- if @queue.size > @max_queue_size
16
- Umbra.logger.warn '[umbra] Shadowing queue at max - dropping items'
17
- return
18
- end
16
+ queue << proc { call!(env) }
19
17
 
20
- request = RequestBuilder.call(env)
18
+ true
19
+ rescue Concurrent::RejectedExecutionError
20
+ Umbra.logger.warn '[umbra] Shadowing queue at max - dropping items'
21
21
 
22
- @count.times { @queue.push(request) }
22
+ false
23
23
  end
24
24
 
25
- private
26
-
27
- # rubocop:disable Metrics/MethodLength
28
- def start_worker!
29
- @lock.synchronize do
30
- return if @started
31
-
32
- @started = true
33
- Umbra.logger.info '[umbra] Starting shadowing threads...'
34
-
35
- workers = (0...@pool).map do |thread_num|
36
- Thread.new do
37
- Umbra.logger.info "[umbra] shadow thread #{thread_num} waiting"
38
-
39
- while (request = @queue.pop)
40
- break if request == @stop
25
+ def call!(env)
26
+ hydra = Typhoeus::Hydra.new
27
+ request = RequestBuilder.call(env)
41
28
 
42
- begin
43
- request.run
44
- rescue StandardError => e
45
- Umbra.logger.warn "[umbra] error in shadow thread #{thread_num}"
46
- Umbra.config.error_handler.call(e)
47
- end
48
- end
49
- end
50
- end
29
+ @count.times { hydra.queue(request) }
51
30
 
52
- at_exit do
53
- @pool.times { @queue.push(@stop) }
54
- workers.map(&:join)
55
- end
56
- end
31
+ hydra.run
57
32
  end
58
- # rubocop:enable Metrics/MethodLength
59
33
  end
60
34
  end
data/lib/umbra/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Umbra
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0.pre'
5
5
  end
data/umbra-rb.gemspec CHANGED
@@ -28,9 +28,12 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'bundler', '~> 2.0'
29
29
  spec.add_development_dependency 'carwow_rubocop'
30
30
  spec.add_development_dependency 'pry'
31
- spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'rack'
32
+ spec.add_development_dependency 'rake', '~> 13.0'
32
33
  spec.add_development_dependency 'rspec', '~> 3.0'
34
+ spec.add_development_dependency 'webmock', '~> 3'
33
35
 
36
+ spec.add_dependency 'concurrent-ruby', '~> 1.1'
34
37
  spec.add_dependency 'multi_json', '~> 1.13'
35
38
  spec.add_dependency 'oj', '~> 3.9'
36
39
  spec.add_dependency 'redis', '~> 4.1'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umbra-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - carwow Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-07 00:00:00.000000000 Z
11
+ date: 2020-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '13.0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '13.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,34 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: concurrent-ruby
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.1'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.1'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: multi_json
85
127
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +194,7 @@ files:
152
194
  - LICENSE.txt
153
195
  - README.md
154
196
  - Rakefile
197
+ - config.ru
155
198
  - lib/umbra.rb
156
199
  - lib/umbra/config.rb
157
200
  - lib/umbra/encoder.rb
@@ -160,7 +203,6 @@ files:
160
203
  - lib/umbra/request_builder.rb
161
204
  - lib/umbra/shadow_requester.rb
162
205
  - lib/umbra/subscriber.rb
163
- - lib/umbra/synchronous_publisher.rb
164
206
  - lib/umbra/version.rb
165
207
  - umbra-rb.gemspec
166
208
  homepage: https://github.com/carwow/umbra
@@ -181,9 +223,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
223
  version: '0'
182
224
  required_rubygems_version: !ruby/object:Gem::Requirement
183
225
  requirements:
184
- - - ">="
226
+ - - ">"
185
227
  - !ruby/object:Gem::Version
186
- version: '0'
228
+ version: 1.3.1
187
229
  requirements: []
188
230
  rubygems_version: 3.0.3
189
231
  signing_key:
@@ -1,7 +0,0 @@
1
- module Umbra
2
- class SynchronousPublisher
3
- def self.call(env, response, encoder: Umbra.encoder, redis: Umbra.redis)
4
- redis.publish(Umbra::CHANNEL, encoder.call(env, response))
5
- end
6
- end
7
- end