umbra-rb 0.3.0.pre → 0.3.0

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
  SHA256:
3
- metadata.gz: b78a47b9846524b89aa167c590d5f912fec5b15e3f257f131bec39717469cbc5
4
- data.tar.gz: '0638dcec00b31af9ef1acb84969fef4dcab5cab1ad24453e52fea11491275655'
3
+ metadata.gz: 4afc323984fc7ba817ef3e2d6d80d7f6de5e628d5efbb149b0b4194285c3adba
4
+ data.tar.gz: bacebcf43acd0a5fe79f59ea5675395cb1201209c30493d4ac3b85f047635722
5
5
  SHA512:
6
- metadata.gz: 38b6958b37872340e07ae3e0f0f18371ae2a7e27787a2521fe9eda8962f8f5e1c7355177677650e811b2e5ba5b1fefb2e228a56993c3a774147191e1df289fe8
7
- data.tar.gz: 6255267c65a90494b301367ccd14645a3e4dc8c481115155fd6c60e94ce1f4ad64d4125b13de2b48d83e84132da1df3a2602689ff35a213f25df2c1dcea30566
6
+ metadata.gz: ea48085756d9af9944a47857499ef825cb0fa8a821db4a79e6f549981da233f31d85f107afcb0084bb703ba9621994936991f0e7e7cdf43787fbe3ee48ee29e3
7
+ data.tar.gz: 2a13babc32f10a410ecee4a10cda257b47080ee83200aaaf2007bff46881b83ba1e11e48d42b795f8714779122712c4e39133ca1245f32b59f39a54b82d3d5a3
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_WITH: "local_deals_service"
data/.standard.yml ADDED
@@ -0,0 +1,2 @@
1
+ ignore:
2
+ - 'lib/umbra/pb/**/*'
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
- # Specify your gem's dependencies in umbra.gemspec
6
5
  gemspec
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "standard/rake"
5
4
 
6
5
  RSpec::Core::RakeTask.new(:spec)
7
6
 
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path("../lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require "bundler/setup"
7
+ require "umbra"
8
+ require "pry"
9
+
10
+ Pry.start
data/config.ru CHANGED
@@ -1,6 +1,11 @@
1
- require 'rack'
2
- require 'rack/lobster'
3
- require 'umbra'
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require "rack"
5
+ require "rack/lobster"
6
+ require "puma"
7
+ require "umbra"
8
+ require "pry"
4
9
 
5
10
  Umbra.configure
6
11
 
data/lib/umbra.rb CHANGED
@@ -1,27 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'typhoeus'
4
- require 'redis'
5
- require 'multi_json'
6
- require 'concurrent'
3
+ require "zeitwerk"
4
+ require "rack"
5
+ require "redis"
6
+ require "concurrent"
7
+
8
+ Zeitwerk::Loader.for_gem.setup
7
9
 
8
10
  module Umbra
9
- autoload :Config, 'umbra/config'
10
- autoload :Encoder, 'umbra/encoder'
11
- autoload :Middleware, 'umbra/middleware'
12
- autoload :Publisher, 'umbra/publisher'
13
- autoload :Subscriber, 'umbra/subscriber'
14
- autoload :RequestBuilder, 'umbra/request_builder'
15
- autoload :ShadowRequester, 'umbra/shadow_requester'
16
- autoload :SynchronousPublisher, 'umbra/synchronous_publisher'
17
- autoload :Version, 'umbra/version'
18
-
19
- CHANNEL = 'umbra_channel'
20
- HEADER_KEY = 'HTTP_X_UMBRA_REQUEST'
21
- HEADER_VALUE = 'true'
11
+ autoload :Pb, "umbra/pb/umbra_pb"
12
+
13
+ CHANNEL = "umbra_channel"
14
+ HEADER_KEY = "HTTP_X_UMBRA_REQUEST"
15
+ HEADER_VALUE = "true"
22
16
 
23
17
  RequestSelector = proc { true }
24
- SuppressErrorHandler = proc { nil }
18
+ SuppressErrorHandler = proc {}
25
19
 
26
20
  class << self
27
21
  attr_reader :config
@@ -32,16 +26,17 @@ module Umbra
32
26
  test_redis_connection!
33
27
  end
34
28
 
35
- def publish(env, response)
29
+ def publish(env)
36
30
  return if umbra_request?(env)
31
+
37
32
  return unless @config
38
- return unless @config.request_selector.call(env, response)
33
+ return unless @config.request_selector.call(env)
39
34
 
40
- env['umbra.request_body'] = request_body(env)
35
+ env["umbra.request_body"] = request_body(env)
41
36
 
42
- @config.publisher.call(env, response)
43
- rescue StandardError => e
44
- @config.error_handler.call(e, env, response)
37
+ @config.publisher.call(env)
38
+ rescue => e
39
+ @config.error_handler.call(e, env)
45
40
  end
46
41
 
47
42
  def redis
@@ -64,7 +59,7 @@ module Umbra
64
59
  private
65
60
 
66
61
  def request_body(env)
67
- io = env.fetch('rack.input')
62
+ io = env.fetch("rack.input")
68
63
  io.rewind
69
64
  body = io.read
70
65
  io.rewind
@@ -73,13 +68,13 @@ module Umbra
73
68
  end
74
69
 
75
70
  def test_redis_connection!
76
- logger.info '[umbra] Testing redis connection...'
71
+ logger.info "[umbra] Testing redis connection..."
77
72
  redis.ping
78
- logger.info '[umbra] redis is alive!'
73
+ logger.info "[umbra] redis is alive!"
79
74
  rescue Redis::BaseError => e
80
75
  logger.warn "[umbra] error while connecting to redis: #{e.message}"
81
76
  reset!
82
- rescue StandardError => e
77
+ rescue => e
83
78
  logger.warn "[umbra] redis is misconfigured: #{e.message}"
84
79
  reset!
85
80
  end
data/lib/umbra/config.rb CHANGED
@@ -9,7 +9,7 @@ module Umbra
9
9
  encoder: Encoder,
10
10
  error_handler: SuppressErrorHandler,
11
11
  redis_options: {},
12
- logger: Logger.new(STDOUT),
12
+ logger: Logger.new($stdout),
13
13
  &block
14
14
  )
15
15
  end
data/lib/umbra/encoder.rb CHANGED
@@ -2,61 +2,47 @@
2
2
 
3
3
  module Umbra
4
4
  class Encoder
5
- def self.call(env, response)
6
- new(env, response).call
5
+ def self.call(env)
6
+ new(env).call
7
7
  end
8
8
 
9
- def initialize(env, response)
9
+ def initialize(env)
10
10
  @env = env
11
- @status, @headers, @body = response
12
- end
13
-
14
- def to_h
15
- @to_h ||=
16
- {
17
- 'request' => {
18
- 'scheme' => @env.fetch('rack.url_scheme'),
19
- 'host' => @env['HTTP_HOST'] || @env.fetch('SERVER_NAME'),
20
- 'uri' => @env.fetch('REQUEST_URI'),
21
- 'port' => @env.fetch('SERVER_PORT'),
22
- 'method' => @env.fetch('REQUEST_METHOD'),
23
- 'query' => @env.fetch('QUERY_STRING'),
24
- 'script_name' => @env.fetch('SCRIPT_NAME'),
25
- 'path_info' => @env.fetch('PATH_INFO'),
26
- 'headers' => request_headers,
27
- 'body' => request_body
28
- },
29
- 'response' => {
30
- 'status' => @status,
31
- 'headers' => @headers,
32
- 'body' => body_string
33
- }
34
- }
35
11
  end
36
12
 
37
13
  def call
38
- @call ||= MultiJson.dump(to_h)
14
+ @call ||= Pb::Message.new(
15
+ method: rack_request.request_method,
16
+ url: rack_request.url,
17
+ body: request_body,
18
+ headers: request_headers
19
+ ).to_proto
20
+ end
21
+
22
+ def ignored_headers
23
+ []
39
24
  end
40
25
 
41
26
  private
42
27
 
43
- def request_headers
44
- @request_headers ||= @env.select { |k, _| k.start_with?('HTTP_') }
28
+ def rack_request
29
+ @rack_request ||= Rack::Request.new(@env)
45
30
  end
46
31
 
47
- def request_body
48
- @env.fetch('umbra.request_body')
32
+ def request_headers
33
+ @request_headers ||=
34
+ @env
35
+ .select { |k, _| k.start_with?("HTTP_") && !ignored_headers.include?(k) }
36
+ .merge(HEADER_KEY => HEADER_VALUE)
37
+ .transform_keys { |k| to_http_header(k) }
49
38
  end
50
39
 
51
- def body_string
52
- @body_string ||=
53
- begin
54
- str = []
55
-
56
- @body.each { |x| str << x.to_s }
40
+ def to_http_header(rack_header)
41
+ rack_header.delete_prefix("HTTP_").downcase.split("_").join("-")
42
+ end
57
43
 
58
- str.join('')
59
- end
44
+ def request_body
45
+ @env.fetch("umbra.request_body")
60
46
  end
61
47
  end
62
48
  end
@@ -5,11 +5,9 @@ module Umbra
5
5
  end
6
6
 
7
7
  def call(env)
8
- response = @app.call(env)
8
+ Umbra.publish(env.dup)
9
9
 
10
- Umbra.publish(env.dup, response.dup)
11
-
12
- response
10
+ @app.call(env)
13
11
  end
14
12
  end
15
13
  end
@@ -0,0 +1,21 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: umbra.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("umbra.proto", :syntax => :proto3) do
8
+ add_message "umbra.pb.Message" do
9
+ optional :method, :string, 1
10
+ optional :url, :string, 2
11
+ map :headers, :string, :string, 3
12
+ optional :body, :bytes, 4
13
+ end
14
+ end
15
+ end
16
+
17
+ module Umbra
18
+ module Pb
19
+ Message = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("umbra.pb.Message").msgclass
20
+ end
21
+ end
@@ -4,6 +4,8 @@ module Umbra
4
4
  DEFAULT_MIN_THREADS = 1
5
5
  DEFAULT_MAX_THREADS = 1
6
6
 
7
+ attr_reader :pool
8
+
7
9
  def initialize(**options)
8
10
  @pool = Concurrent::CachedThreadPool.new(
9
11
  min_threads: options.fetch(:min_threads, DEFAULT_MIN_THREADS),
@@ -13,18 +15,18 @@ module Umbra
13
15
  )
14
16
  end
15
17
 
16
- def call(env, response, encoder: Umbra.encoder, redis: Umbra.redis)
17
- @pool << proc { call!(env, response, encoder: encoder, redis: redis) }
18
+ def call(env, encoder: Umbra.encoder, redis: Umbra.redis)
19
+ @pool << proc { call!(env, encoder: encoder, redis: redis) }
18
20
 
19
21
  true
20
22
  rescue Concurrent::RejectedExecutionError
21
- Umbra.logger.warn '[umbra] Queue at max - dropping items'
23
+ Umbra.logger.warn "[umbra] Queue at max - dropping items"
22
24
 
23
25
  false
24
26
  end
25
27
 
26
- def call!(env, response, encoder: Umbra.encoder, redis: Umbra.redis)
27
- redis.publish(Umbra::CHANNEL, encoder.call(env, response))
28
+ def call!(env, encoder: Umbra.encoder, redis: Umbra.redis)
29
+ redis.publish(Umbra::CHANNEL, encoder.call(env))
28
30
  end
29
31
  end
30
32
  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.3.0.pre'
4
+ VERSION = "0.3.0"
5
5
  end
data/umbra-rb.gemspec CHANGED
@@ -1,41 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'umbra/version'
5
+
6
+ require "umbra/version"
6
7
 
7
8
  Gem::Specification.new do |spec|
8
- spec.name = 'umbra-rb'
9
- spec.version = Umbra::VERSION
10
- spec.authors = ['carwow Developers']
11
- spec.email = ['developers@carwow.co.uk']
9
+ spec.name = "umbra-rb"
10
+ spec.version = Umbra::VERSION
11
+ spec.authors = ["carwow Developers"]
12
+ spec.email = ["developers@carwow.co.uk"]
13
+
14
+ spec.summary = "A shadow requesting library for rack based applications"
15
+ spec.homepage = "https://github.com/carwow/umbra"
16
+ spec.license = "MIT"
12
17
 
13
- spec.summary = 'A shadow requesting library for rack based applications'
14
- spec.homepage = 'https://github.com/carwow/umbra'
15
- spec.license = 'MIT'
18
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["github_repo"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = spec.homepage
16
22
 
17
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
- spec.metadata['homepage_uri'] = spec.homepage
19
- spec.metadata['source_code_uri'] = spec.homepage
23
+ spec.require_paths = ["lib"]
20
24
 
21
- # Specify which files should be added to the gem when it is released.
22
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ `git ls-files -z`
27
+ .split("\x0")
28
+ .reject { |f| f.match(%r{^(test|spec|features)/}) }
25
29
  end
26
- spec.require_paths = ['lib']
27
-
28
- spec.add_development_dependency 'bundler', '~> 2.0'
29
- spec.add_development_dependency 'carwow_rubocop'
30
- spec.add_development_dependency 'pry'
31
- spec.add_development_dependency 'rack'
32
- spec.add_development_dependency 'rake', '~> 13.0'
33
- spec.add_development_dependency 'rspec', '~> 3.0'
34
- spec.add_development_dependency 'webmock', '~> 3'
35
-
36
- spec.add_dependency 'concurrent-ruby', '~> 1.1'
37
- spec.add_dependency 'multi_json', '~> 1.13'
38
- spec.add_dependency 'oj', '~> 3.9'
39
- spec.add_dependency 'redis', '~> 4.1'
40
- spec.add_dependency 'typhoeus', '~> 1.3'
30
+
31
+ spec.add_development_dependency "bundler", "~> 2.0"
32
+ spec.add_development_dependency "standard"
33
+ spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "rake", "~> 13.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "rack-test"
37
+ spec.add_development_dependency "puma"
38
+
39
+ spec.add_dependency "concurrent-ruby", "~> 1.1"
40
+ spec.add_dependency "redis", "~> 4.1"
41
+ spec.add_dependency "google-protobuf", "~> 3"
42
+ spec.add_dependency "rack", "~> 2"
43
+ spec.add_dependency "zeitwerk", "~> 2"
41
44
  end
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.3.0.pre
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - carwow Developers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-21 00:00:00.000000000 Z
11
+ date: 2021-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: carwow_rubocop
28
+ name: standard
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -53,61 +53,61 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rack
56
+ name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '13.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
- version: '0'
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rake
70
+ name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '13.0'
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
- version: '13.0'
82
+ version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec
84
+ name: rack-test
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '3.0'
89
+ version: '0'
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
- version: '3.0'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: webmock
98
+ name: puma
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '3'
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '3'
110
+ version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: concurrent-ruby
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -123,86 +123,81 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.1'
125
125
  - !ruby/object:Gem::Dependency
126
- name: multi_json
126
+ name: redis
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '1.13'
131
+ version: '4.1'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '1.13'
138
+ version: '4.1'
139
139
  - !ruby/object:Gem::Dependency
140
- name: oj
140
+ name: google-protobuf
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '3.9'
145
+ version: '3'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '3.9'
152
+ version: '3'
153
153
  - !ruby/object:Gem::Dependency
154
- name: redis
154
+ name: rack
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '4.1'
159
+ version: '2'
160
160
  type: :runtime
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '4.1'
166
+ version: '2'
167
167
  - !ruby/object:Gem::Dependency
168
- name: typhoeus
168
+ name: zeitwerk
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '1.3'
173
+ version: '2'
174
174
  type: :runtime
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '1.3'
181
- description:
180
+ version: '2'
181
+ description:
182
182
  email:
183
183
  - developers@carwow.co.uk
184
184
  executables: []
185
185
  extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
- - ".circleci/config.yml"
189
- - ".gitignore"
188
+ - ".bundle/config"
190
189
  - ".rspec"
191
- - ".rubocop.yml"
190
+ - ".standard.yml"
192
191
  - Gemfile
193
- - Gemfile.lock
194
- - LICENSE.txt
195
- - README.md
196
192
  - Rakefile
193
+ - bin/console
197
194
  - config.ru
198
195
  - lib/umbra.rb
199
196
  - lib/umbra/config.rb
200
197
  - lib/umbra/encoder.rb
201
198
  - lib/umbra/middleware.rb
199
+ - lib/umbra/pb/umbra_pb.rb
202
200
  - lib/umbra/publisher.rb
203
- - lib/umbra/request_builder.rb
204
- - lib/umbra/shadow_requester.rb
205
- - lib/umbra/subscriber.rb
206
201
  - lib/umbra/version.rb
207
202
  - umbra-rb.gemspec
208
203
  homepage: https://github.com/carwow/umbra
@@ -211,8 +206,9 @@ licenses:
211
206
  metadata:
212
207
  allowed_push_host: https://rubygems.org
213
208
  homepage_uri: https://github.com/carwow/umbra
209
+ github_repo: https://github.com/carwow/umbra
214
210
  source_code_uri: https://github.com/carwow/umbra
215
- post_install_message:
211
+ post_install_message:
216
212
  rdoc_options: []
217
213
  require_paths:
218
214
  - lib
@@ -223,12 +219,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
219
  version: '0'
224
220
  required_rubygems_version: !ruby/object:Gem::Requirement
225
221
  requirements:
226
- - - ">"
222
+ - - ">="
227
223
  - !ruby/object:Gem::Version
228
- version: 1.3.1
224
+ version: '0'
229
225
  requirements: []
230
- rubygems_version: 3.0.3
231
- signing_key:
226
+ rubygems_version: 3.1.4
227
+ signing_key:
232
228
  specification_version: 4
233
229
  summary: A shadow requesting library for rack based applications
234
230
  test_files: []
data/.circleci/config.yml DELETED
@@ -1,59 +0,0 @@
1
- ruby: &ruby
2
- image: carwow/ruby-ci:2.6
3
-
4
- redis: &redis
5
- image: redis
6
-
7
- version: 2
8
-
9
- jobs:
10
- bundle:
11
- working_directory: ~/umbra
12
- docker:
13
- - *ruby
14
- steps:
15
- - checkout
16
- - restore_cache:
17
- keys:
18
- - bundle-{{ checksum "Gemfile.lock" }}
19
- - bundle-
20
- - run: |
21
- bundle config --local path vendor/bundle &&
22
- bundle check || bundle install --jobs=4 --retry=3
23
- - save_cache:
24
- key: bundle-{{ checksum "Gemfile.lock" }}
25
- paths: [~/umbra/vendor/bundle]
26
- - persist_to_workspace:
27
- root: '~'
28
- paths: [umbra]
29
-
30
- rubocop:
31
- working_directory: ~/umbra
32
- docker:
33
- - *ruby
34
- steps:
35
- - attach_workspace:
36
- at: '~'
37
- - run: bundle exec rubocop
38
-
39
- tests:
40
- working_directory: ~/umbra
41
- docker:
42
- - *ruby
43
- - *redis
44
- steps:
45
- - attach_workspace:
46
- at: '~'
47
- - run: |
48
- bundle exec rspec
49
-
50
- workflows:
51
- version: 2
52
- build:
53
- jobs:
54
- - bundle
55
- - rubocop:
56
- requires: [bundle]
57
- - tests:
58
- requires: [bundle]
59
-
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
- *.gem
data/.rubocop.yml DELETED
@@ -1,9 +0,0 @@
1
- inherit_gem:
2
- carwow_rubocop:
3
- - default.yml
4
-
5
- Metrics/MethodLength:
6
- Max: 20
7
-
8
- Metrics/AbcSize:
9
- Max: 20
data/Gemfile.lock DELETED
@@ -1,93 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- umbra-rb (0.3.0.pre)
5
- concurrent-ruby (~> 1.1)
6
- multi_json (~> 1.13)
7
- oj (~> 3.9)
8
- redis (~> 4.1)
9
- typhoeus (~> 1.3)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- addressable (2.7.0)
15
- public_suffix (>= 2.0.2, < 5.0)
16
- ast (2.4.0)
17
- carwow_rubocop (3.2.1)
18
- rubocop (>= 0.78)
19
- rubocop-performance
20
- rubocop-rspec
21
- coderay (1.1.2)
22
- concurrent-ruby (1.1.5)
23
- crack (0.4.3)
24
- safe_yaml (~> 1.0.0)
25
- diff-lcs (1.3)
26
- ethon (0.12.0)
27
- ffi (>= 1.3.0)
28
- ffi (1.12.1)
29
- hashdiff (1.0.0)
30
- jaro_winkler (1.5.4)
31
- method_source (0.9.2)
32
- multi_json (1.14.1)
33
- oj (3.10.1)
34
- parallel (1.19.1)
35
- parser (2.7.0.2)
36
- ast (~> 2.4.0)
37
- pry (0.12.2)
38
- coderay (~> 1.1.0)
39
- method_source (~> 0.9.0)
40
- public_suffix (4.0.3)
41
- rack (2.1.1)
42
- rainbow (3.0.0)
43
- rake (13.0.1)
44
- redis (4.1.3)
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)
52
- diff-lcs (>= 1.2.0, < 2.0)
53
- rspec-support (~> 3.9.0)
54
- rspec-mocks (3.9.0)
55
- diff-lcs (>= 1.2.0, < 2.0)
56
- rspec-support (~> 3.9.0)
57
- rspec-support (3.9.0)
58
- rubocop (0.79.0)
59
- jaro_winkler (~> 1.5.1)
60
- parallel (~> 1.10)
61
- parser (>= 2.7.0.1)
62
- rainbow (>= 2.2.2, < 4.0)
63
- ruby-progressbar (~> 1.7)
64
- unicode-display_width (>= 1.4.0, < 1.7)
65
- rubocop-performance (1.5.2)
66
- rubocop (>= 0.71.0)
67
- rubocop-rspec (1.37.1)
68
- rubocop (>= 0.68.1)
69
- ruby-progressbar (1.10.1)
70
- safe_yaml (1.0.5)
71
- typhoeus (1.3.1)
72
- ethon (>= 0.9.0)
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)
78
-
79
- PLATFORMS
80
- ruby
81
-
82
- DEPENDENCIES
83
- bundler (~> 2.0)
84
- carwow_rubocop
85
- pry
86
- rack
87
- rake (~> 13.0)
88
- rspec (~> 3.0)
89
- umbra-rb!
90
- webmock (~> 3)
91
-
92
- BUNDLED WITH
93
- 2.0.2
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2019 Christian Gregg
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/README.md DELETED
@@ -1,100 +0,0 @@
1
- # umbra :waning_crescent_moon:
2
-
3
- > **umbra** /ˈʌmbrə/
4
- >
5
- > noun
6
- > 1. the fully shaded inner region of a shadow cast by an opaque object, especially the area on the earth or moon experiencing the total phase of an eclipse.
7
- > 2. shadow or darkness.
8
- > "an impenetrable umbra seemed to fill every inch of the museum"
9
-
10
- `umbra` is a rack middleware that allows you to create shadow requests via a redis pub/sub channel.
11
-
12
- # Installation
13
-
14
- Add this to your `Gemfile`
15
-
16
- ```ruby
17
- gem 'umbra-rb'
18
- ```
19
-
20
- And then execute:
21
-
22
- $ bundle
23
-
24
- Or install it yourself as:
25
-
26
- $ gem install umbra-rb
27
-
28
-
29
- ## Usage
30
-
31
- A minimal rack application using `umbra` would look like this:
32
-
33
- ```ruby
34
- # /config.ru
35
- require 'rack'
36
- require 'rack/lobster'
37
- require 'umbra'
38
-
39
- Umbra.configure
40
-
41
- use Umbra::Middleware
42
- run Rack::Lobster.new
43
-
44
- ```
45
-
46
- If using Rails you can achieve the same via an initializer:
47
-
48
- ```ruby
49
- # /config/initializers/umbra.rb
50
- require 'umbra'
51
-
52
- Umbra.configure
53
-
54
- Rails.application.config.middleware.use(Umbra::Middleware)
55
- ```
56
-
57
- Then, in another process, you can start receiving each request via an `Umbra::Subscriber`.
58
- `Umbra::Subscriber` can be initialized with anything response to `.call`. For example:
59
-
60
- ```ruby
61
- Umbra::Subscriber.new(
62
- proc { |payload| puts "New Request: #{payload}" }
63
- ).start
64
- ```
65
-
66
- The `payload` is the encoded request and response, as defined by the configured encoder. By default, this is `Umbra::Encoder`.
67
-
68
- `umbra` also provides some helper classes for common use cases:
69
-
70
- - `Umbra::RequestBuilder` takes the default encoding and returns a `Typhoeus::Request` object.
71
- - `Umbra::ShadowRequester` can be configured to shadow requests `count:` times using a `pool:` of threads via a thread queue.
72
- - More to come...
73
-
74
-
75
- # Config
76
-
77
- `umbra` allows you to add custom configuration by passing a block to `Umbra.configure`. You may pass custom configuration in the following form:
78
-
79
- ```ruby
80
- Umbra.configure do |config|
81
- config.<config_option> = <config_value>
82
- end
83
- ```
84
-
85
- | config_option | default | description |
86
- | ------------- | ------- | ----------- |
87
- | publisher | `Umbra::Publisher` | Must respond to `call`. By default, pushes the encoded rack request/response to a `Queue` that is consumed in a different thread and publishes to `redis`. |
88
- | request_selector | `Umbra::RequestSelector` / `proc { true }` | Must respond to `call`. Determines whether request/response will be published |
89
- | encoder | `Umbra::Encoder` | Must response to `call`. Encodes the rack request/response for publishing |
90
- | error_handler | `Umbra::SupressErrorHandler` / `proc { nil }` | Must respond to `call`. Called on exception, is always passed the exception as first argument, *may* be passed rack environment and response. |
91
- | redis_options | `{}` | Hash of options passed to `Redis` client. See [`Redis::Client` docs](https://www.rubydoc.info/gems/redis/Redis/Client) |
92
- | logger | `Logger.new(STDOUT)` | The logger to be used. |
93
-
94
- ## Contributing
95
-
96
- Bug reports and pull requests are welcome on GitHub at https://github.com/carwow/umbra.
97
-
98
- ## License
99
-
100
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Umbra
4
- class RequestBuilder
5
- UMBRA_HEADERS = {
6
- Umbra::HEADER_KEY => Umbra::HEADER_VALUE,
7
- 'HTTP_CACHE_CONTROL' => 'no-cache, no-store, private, max-age=0'
8
- }.freeze
9
-
10
- class << self
11
- def call(env)
12
- Typhoeus::Request.new(
13
- base_url(env) + url(env),
14
- method: method(env),
15
- body: body(env),
16
- headers: headers(env)
17
- )
18
- end
19
-
20
- private
21
-
22
- def headers(env)
23
- request(env)
24
- .fetch('headers')
25
- .merge(UMBRA_HEADERS)
26
- .transform_keys { |key| key.split('_').drop(1).map(&:capitalize).join('-') }
27
- end
28
-
29
- def method(env)
30
- request(env).fetch('method').downcase.to_sym
31
- end
32
-
33
- def body(env)
34
- request(env).fetch('body')
35
- end
36
-
37
- def url(env)
38
- request = request(env)
39
- query = request.fetch('query')
40
- path = request.fetch('script_name') + request.fetch('path_info')
41
-
42
- query.empty? ? path : path + "?#{query}"
43
- end
44
-
45
- def base_url(env)
46
- request = request(env)
47
- scheme = request.fetch('scheme')
48
- host = request.fetch('host')
49
-
50
- "#{scheme}://#{host}"
51
- end
52
-
53
- def request(env)
54
- env.fetch('request')
55
- end
56
- end
57
- end
58
- end
@@ -1,34 +0,0 @@
1
- module Umbra
2
- class ShadowRequester
3
- attr_reader :queue, :count
4
-
5
- def initialize(count: 1, pool: 1, max_queue_size: 100)
6
- @count = count
7
- @queue ||= Concurrent::CachedThreadPool.new(
8
- min_threads: 1,
9
- max_threads: pool,
10
- max_queue: max_queue_size,
11
- fallback_policy: :abort
12
- )
13
- end
14
-
15
- def call(env)
16
- queue << proc { call!(env) }
17
-
18
- true
19
- rescue Concurrent::RejectedExecutionError
20
- Umbra.logger.warn '[umbra] Shadowing queue at max - dropping items'
21
-
22
- false
23
- end
24
-
25
- def call!(env)
26
- hydra = Typhoeus::Hydra.new
27
- request = RequestBuilder.call(env)
28
-
29
- @count.times { hydra.queue(request) }
30
-
31
- hydra.run
32
- end
33
- end
34
- end
@@ -1,15 +0,0 @@
1
- module Umbra
2
- class Subscriber
3
- def initialize(worker)
4
- @worker = worker
5
- end
6
-
7
- def start
8
- Umbra.redis.subscribe(Umbra::CHANNEL) do |on|
9
- on.message do |_, message|
10
- @worker.call(MultiJson.load(message))
11
- end
12
- end
13
- end
14
- end
15
- end