rack-cargo 0.9.0 → 0.9.1

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: 74705fb4f2b4e71ae109218d020b4a656ecee186
4
- data.tar.gz: 53678530b07f570861049feed0169459d528a9ae
3
+ metadata.gz: 18247c076dabaec48022379801e52ce2c0f42b7d
4
+ data.tar.gz: ac28a8c8840c795e602269072b6047969b092b86
5
5
  SHA512:
6
- metadata.gz: d39972558dd1a23a65c1f676ff0156861126ce4520a7532d34a0412356bfb75fbcb6788ce6d8520988887279a63ea9189beac0fdb5efce04f6094964a354b227
7
- data.tar.gz: 5fb134a797e14a55506dcac06f0a8bf6782859100e23a5fb34e0bda3d5e9767b8b6105feb87f7a08f2a663a13fc64a3052cd005e4bf539bdc03ed1afe32f3a76
6
+ metadata.gz: 7b0c706fe67a05b6bc27555d3387c42cae772fa35c8f1f3fa62b5d43cc788dc3ce15c2bb9bd1a8d8ca9f1be8b7da031065e95c55968df3d54558a340f9fc4da0
7
+ data.tar.gz: 7ee5d82be0ef27a7cf6bf5946d6cd2f823c47c4d656ab1debcfe9da043be415a2600962b2f8f24334500aae936d2c25c7a63babbf82f9d373b6ce6e41a2887e5
data/README.md CHANGED
@@ -40,7 +40,8 @@ Initialize the middleware:
40
40
 
41
41
  ```ruby
42
42
  Rack::Cargo.configure do |config|
43
- config.batch_path = '/batch'
43
+ config.batch_path = '/batch'
44
+ config.timeout = 1
44
45
  end
45
46
  ```
46
47
 
@@ -154,6 +155,20 @@ end
154
155
 
155
156
  Now your processors will be included in the pipeline.
156
157
 
158
+ ### Individual request timeout
159
+
160
+ Individual requests in batch will be dropped after execution exceeds configured timeout. Default timeout is 1 second.
161
+
162
+ Specify timeout for single request in configuration:
163
+
164
+ ```ruby
165
+ Rack::Cargo.configure do |config|
166
+ config.timeout = 1
167
+ end
168
+ ```
169
+
170
+ Timed out requests' response is with status 504 (Gateway timeout) and with empty headers, body.
171
+
157
172
  ## Development
158
173
 
159
174
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/rack/cargo.rb CHANGED
@@ -12,6 +12,7 @@ module Rack
12
12
  ENV_PATH = "PATH_INFO"
13
13
  ENV_INPUT = "rack.input"
14
14
  ENV_METHOD = "REQUEST_METHOD"
15
+ ENV_QUERY_STRING = "QUERY_STRING"
15
16
 
16
17
  REQUEST_NAME = "name"
17
18
  REQUEST_PATH = "path"
@@ -19,6 +20,7 @@ module Rack
19
20
  REQUEST_BODY = "body"
20
21
 
21
22
  RESPONSE_NAME = "name"
23
+ RESPONSE_PATH = "path"
22
24
  RESPONSE_STATUS = "status"
23
25
  RESPONSE_HEADERS = "headers"
24
26
  RESPONSE_BODY = "body"
@@ -5,6 +5,7 @@ module Rack
5
5
  class Configuration
6
6
  attr_accessor :batch_path
7
7
  attr_accessor :processors
8
+ attr_accessor :timeout
8
9
 
9
10
  def initialize
10
11
  self.batch_path = "/batch"
@@ -14,6 +15,7 @@ module Rack
14
15
  RequestExecutor,
15
16
  ResponseBuilder
16
17
  ]
18
+ self.timeout = 1 # seconds
17
19
  end
18
20
  end
19
21
  end
@@ -7,9 +7,13 @@ module Rack
7
7
  module RequestEnvBuilder
8
8
  def self.call(request, state)
9
9
  request_env = state.fetch(:env).deep_dup
10
- request_env[ENV_PATH] = request[REQUEST_PATH]
10
+
11
+ path, query_string = request[REQUEST_PATH].split("?", 2)
12
+ request_env[ENV_PATH] = path
13
+ request_env[ENV_QUERY_STRING] = query_string || ""
11
14
  request_env[ENV_METHOD] = request[REQUEST_METHOD]
12
15
  request_env[ENV_INPUT] = StringIO.new(request[REQUEST_BODY].to_json)
16
+
13
17
  state[:request_env] = request_env
14
18
  end
15
19
  end
@@ -3,18 +3,33 @@
3
3
  module Rack
4
4
  module Cargo
5
5
  module RequestExecutor
6
- def self.call(_request, state)
7
- app = state.fetch(:app)
8
- request_env = state.fetch(:request_env)
6
+ class << self
7
+ def call(_request, state)
8
+ app = state.fetch(:app)
9
+ request_env = state.fetch(:request_env)
9
10
 
10
- status, headers, body = app.call(request_env)
11
- body.close if body.respond_to?(:close)
11
+ status, headers, body = with_timeout(Rack::Cargo.config.timeout) do
12
+ app.call(request_env)
13
+ end
12
14
 
13
- state[:app_response] = {
14
- status: status,
15
- headers: headers,
16
- body: body
17
- }
15
+ body.close if body.respond_to?(:close)
16
+
17
+ state[:app_response] = {
18
+ status: status,
19
+ headers: headers,
20
+ body: body
21
+ }
22
+ end
23
+
24
+ def with_timeout(seconds, &block)
25
+ Timeout.timeout(seconds, &block)
26
+ rescue Timeout::Error
27
+ timeout_response
28
+ end
29
+
30
+ def timeout_response
31
+ [504, {}, ["{}"]]
32
+ end
18
33
  end
19
34
  end
20
35
  end
@@ -7,19 +7,31 @@ module Rack
7
7
  def call(request, state)
8
8
  app_response = state.fetch(:app_response)
9
9
 
10
- name = request.fetch("name", autogenerated_name)
10
+ name = request.fetch(REQUEST_NAME, autogenerated_name)
11
11
 
12
12
  state[:response] = {
13
13
  RESPONSE_NAME => name,
14
+ RESPONSE_PATH => request.fetch(REQUEST_PATH),
14
15
  RESPONSE_STATUS => app_response.fetch(:status),
15
16
  RESPONSE_HEADERS => app_response.fetch(:headers),
16
- RESPONSE_BODY => JSON.parse(app_response.fetch(:body).join)
17
+ RESPONSE_BODY => response_body(app_response.fetch(:body))
17
18
  }
18
19
  end
19
20
 
21
+ private
22
+
20
23
  def autogenerated_name
21
24
  "unnamed_#{SecureRandom.hex(6)}"
22
25
  end
26
+
27
+ # Transform body object to String according to
28
+ # Rack specification requirements.
29
+ def response_body(app_response_body)
30
+ response_string = ""
31
+ app_response_body.each { |piece| response_string += piece }
32
+
33
+ JSON.parse(response_string)
34
+ end
23
35
  end
24
36
  end
25
37
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  module Cargo
5
- VERSION = "0.9.0"
5
+ VERSION = "0.9.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-cargo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Murdho
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-24 00:00:00.000000000 Z
11
+ date: 2017-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler