restify 1.15.2 → 2.0.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 +4 -4
- data/CHANGELOG.md +34 -2
- data/README.md +23 -31
- data/doc/file.README.html +192 -0
- data/lib/restify/adapter/base.rb +4 -0
- data/lib/restify/adapter/telemetry.rb +54 -0
- data/lib/restify/adapter/typhoeus.rb +37 -4
- data/lib/restify/context.rb +3 -3
- data/lib/restify/error.rb +2 -2
- data/lib/restify/link.rb +4 -4
- data/lib/restify/processors/base/parsing.rb +2 -21
- data/lib/restify/processors/base.rb +1 -1
- data/lib/restify/promise.rb +2 -2
- data/lib/restify/registry.rb +1 -1
- data/lib/restify/relation.rb +45 -17
- data/lib/restify/request.rb +6 -6
- data/lib/restify/timeout.rb +2 -2
- data/lib/restify/version.rb +3 -3
- data/lib/restify.rb +0 -1
- data/spec/restify/cache_spec.rb +16 -12
- data/spec/restify/context_spec.rb +8 -3
- data/spec/restify/error_spec.rb +13 -16
- data/spec/restify/features/head_requests_spec.rb +5 -4
- data/spec/restify/features/opentelemetry_spec.rb +46 -0
- data/spec/restify/features/request_bodies_spec.rb +8 -8
- data/spec/restify/features/request_errors_spec.rb +2 -2
- data/spec/restify/features/request_headers_spec.rb +3 -6
- data/spec/restify/features/response_errors_spec.rb +1 -1
- data/spec/restify/features/webmock_spec.rb +27 -0
- data/spec/restify/global_spec.rb +10 -10
- data/spec/restify/processors/base_spec.rb +6 -7
- data/spec/restify/processors/json_spec.rb +21 -62
- data/spec/restify/processors/msgpack_spec.rb +33 -70
- data/spec/restify/promise_spec.rb +31 -31
- data/spec/restify/registry_spec.rb +5 -7
- data/spec/restify/relation_spec.rb +185 -7
- data/spec/restify/resource_spec.rb +47 -53
- data/spec/restify/timeout_spec.rb +3 -3
- data/spec/restify_spec.rb +12 -73
- data/spec/spec_helper.rb +12 -15
- data/spec/support/opentelemetry.rb +29 -0
- data/spec/support/stub_server.rb +4 -0
- metadata +37 -64
- data/lib/restify/adapter/em.rb +0 -134
- data/lib/restify/adapter/pooled_em.rb +0 -269
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-16 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
@@ -52,26 +51,6 @@ dependencies:
|
|
52
51
|
- - "~>"
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '1.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: hashie
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '3.3'
|
62
|
-
- - "<"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '5.0'
|
65
|
-
type: :runtime
|
66
|
-
prerelease: false
|
67
|
-
version_requirements: !ruby/object:Gem::Requirement
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: '3.3'
|
72
|
-
- - "<"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '5.0'
|
75
54
|
- !ruby/object:Gem::Dependency
|
76
55
|
name: hitimes
|
77
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,51 +94,65 @@ dependencies:
|
|
115
94
|
- !ruby/object:Gem::Version
|
116
95
|
version: '1.2'
|
117
96
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
97
|
+
name: opentelemetry-api
|
119
98
|
requirement: !ruby/object:Gem::Requirement
|
120
99
|
requirements:
|
121
|
-
- - "
|
100
|
+
- - "~>"
|
122
101
|
- !ruby/object:Gem::Version
|
123
|
-
version: '0'
|
102
|
+
version: '1.0'
|
124
103
|
type: :runtime
|
125
104
|
prerelease: false
|
126
105
|
version_requirements: !ruby/object:Gem::Requirement
|
127
106
|
requirements:
|
128
|
-
- - "
|
107
|
+
- - "~>"
|
129
108
|
- !ruby/object:Gem::Version
|
130
|
-
version: '0'
|
109
|
+
version: '1.0'
|
131
110
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
111
|
+
name: opentelemetry-common
|
133
112
|
requirement: !ruby/object:Gem::Requirement
|
134
113
|
requirements:
|
135
|
-
- - "
|
114
|
+
- - ">="
|
136
115
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
116
|
+
version: '0'
|
138
117
|
type: :runtime
|
139
118
|
prerelease: false
|
140
119
|
version_requirements: !ruby/object:Gem::Requirement
|
141
120
|
requirements:
|
142
|
-
- - "
|
121
|
+
- - ">="
|
143
122
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
123
|
+
version: '0'
|
145
124
|
- !ruby/object:Gem::Dependency
|
146
|
-
name:
|
125
|
+
name: rack
|
147
126
|
requirement: !ruby/object:Gem::Requirement
|
148
127
|
requirements:
|
149
128
|
- - ">="
|
150
129
|
- !ruby/object:Gem::Version
|
151
130
|
version: '0'
|
152
|
-
type: :
|
131
|
+
type: :runtime
|
153
132
|
prerelease: false
|
154
133
|
version_requirements: !ruby/object:Gem::Requirement
|
155
134
|
requirements:
|
156
135
|
- - ">="
|
157
136
|
- !ruby/object:Gem::Version
|
158
137
|
version: '0'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: typhoeus
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '1.3'
|
145
|
+
type: :runtime
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '1.3'
|
159
152
|
description: An experimental hypermedia REST client that uses parallel, keep-alive
|
160
153
|
and pipelined requests by default.
|
161
154
|
email:
|
162
|
-
-
|
155
|
+
- jgraichen@altimos.de
|
163
156
|
executables: []
|
164
157
|
extensions: []
|
165
158
|
extra_rdoc_files: []
|
@@ -167,10 +160,10 @@ files:
|
|
167
160
|
- CHANGELOG.md
|
168
161
|
- LICENSE.txt
|
169
162
|
- README.md
|
163
|
+
- doc/file.README.html
|
170
164
|
- lib/restify.rb
|
171
165
|
- lib/restify/adapter/base.rb
|
172
|
-
- lib/restify/adapter/
|
173
|
-
- lib/restify/adapter/pooled_em.rb
|
166
|
+
- lib/restify/adapter/telemetry.rb
|
174
167
|
- lib/restify/adapter/typhoeus.rb
|
175
168
|
- lib/restify/cache.rb
|
176
169
|
- lib/restify/context.rb
|
@@ -194,10 +187,12 @@ files:
|
|
194
187
|
- spec/restify/context_spec.rb
|
195
188
|
- spec/restify/error_spec.rb
|
196
189
|
- spec/restify/features/head_requests_spec.rb
|
190
|
+
- spec/restify/features/opentelemetry_spec.rb
|
197
191
|
- spec/restify/features/request_bodies_spec.rb
|
198
192
|
- spec/restify/features/request_errors_spec.rb
|
199
193
|
- spec/restify/features/request_headers_spec.rb
|
200
194
|
- spec/restify/features/response_errors_spec.rb
|
195
|
+
- spec/restify/features/webmock_spec.rb
|
201
196
|
- spec/restify/global_spec.rb
|
202
197
|
- spec/restify/link_spec.rb
|
203
198
|
- spec/restify/processors/base_spec.rb
|
@@ -210,13 +205,13 @@ files:
|
|
210
205
|
- spec/restify/timeout_spec.rb
|
211
206
|
- spec/restify_spec.rb
|
212
207
|
- spec/spec_helper.rb
|
208
|
+
- spec/support/opentelemetry.rb
|
213
209
|
- spec/support/stub_server.rb
|
214
210
|
homepage: https://github.com/jgraichen/restify
|
215
211
|
licenses:
|
216
212
|
- LGPL-3.0+
|
217
213
|
metadata:
|
218
214
|
rubygems_mfa_required: 'true'
|
219
|
-
post_install_message:
|
220
215
|
rdoc_options: []
|
221
216
|
require_paths:
|
222
217
|
- lib
|
@@ -224,36 +219,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
224
219
|
requirements:
|
225
220
|
- - ">="
|
226
221
|
- !ruby/object:Gem::Version
|
227
|
-
version:
|
222
|
+
version: 3.1.0
|
228
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
224
|
requirements:
|
230
225
|
- - ">="
|
231
226
|
- !ruby/object:Gem::Version
|
232
227
|
version: '0'
|
233
228
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
235
|
-
signing_key:
|
229
|
+
rubygems_version: 3.6.2
|
236
230
|
specification_version: 4
|
237
231
|
summary: An experimental hypermedia REST client.
|
238
|
-
test_files:
|
239
|
-
- spec/restify/cache_spec.rb
|
240
|
-
- spec/restify/context_spec.rb
|
241
|
-
- spec/restify/error_spec.rb
|
242
|
-
- spec/restify/features/head_requests_spec.rb
|
243
|
-
- spec/restify/features/request_bodies_spec.rb
|
244
|
-
- spec/restify/features/request_errors_spec.rb
|
245
|
-
- spec/restify/features/request_headers_spec.rb
|
246
|
-
- spec/restify/features/response_errors_spec.rb
|
247
|
-
- spec/restify/global_spec.rb
|
248
|
-
- spec/restify/link_spec.rb
|
249
|
-
- spec/restify/processors/base_spec.rb
|
250
|
-
- spec/restify/processors/json_spec.rb
|
251
|
-
- spec/restify/processors/msgpack_spec.rb
|
252
|
-
- spec/restify/promise_spec.rb
|
253
|
-
- spec/restify/registry_spec.rb
|
254
|
-
- spec/restify/relation_spec.rb
|
255
|
-
- spec/restify/resource_spec.rb
|
256
|
-
- spec/restify/timeout_spec.rb
|
257
|
-
- spec/restify_spec.rb
|
258
|
-
- spec/spec_helper.rb
|
259
|
-
- spec/support/stub_server.rb
|
232
|
+
test_files: []
|
data/lib/restify/adapter/em.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eventmachine'
|
4
|
-
require 'em-http-request'
|
5
|
-
|
6
|
-
module Restify
|
7
|
-
module Adapter
|
8
|
-
class EM < Base
|
9
|
-
class Connection
|
10
|
-
class << self
|
11
|
-
def open(uri)
|
12
|
-
connections[uri.origin] ||= new uri.origin
|
13
|
-
end
|
14
|
-
|
15
|
-
def connections
|
16
|
-
@connections ||= {}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :origin
|
21
|
-
|
22
|
-
def initialize(origin)
|
23
|
-
@origin = origin
|
24
|
-
@pipeline = true
|
25
|
-
end
|
26
|
-
|
27
|
-
def requests
|
28
|
-
@requests ||= []
|
29
|
-
end
|
30
|
-
|
31
|
-
# rubocop:disable Style/IdenticalConditionalBranches
|
32
|
-
def call(request, writer, retried: false)
|
33
|
-
if requests.empty?
|
34
|
-
requests << [request, writer, retried]
|
35
|
-
process_next
|
36
|
-
else
|
37
|
-
requests << [request, writer, retried]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
# rubocop:enable all
|
41
|
-
|
42
|
-
def connection
|
43
|
-
@connection ||= EventMachine::HttpRequest.new(origin)
|
44
|
-
end
|
45
|
-
|
46
|
-
def pipeline?
|
47
|
-
@pipeline
|
48
|
-
end
|
49
|
-
|
50
|
-
def process_next
|
51
|
-
return if requests.empty?
|
52
|
-
|
53
|
-
request, writer, retried = pipeline? ? requests.shift : requests.first
|
54
|
-
begin
|
55
|
-
req = connection.send request.method.downcase,
|
56
|
-
keepalive: true,
|
57
|
-
redirects: 3,
|
58
|
-
path: request.uri.normalized_path,
|
59
|
-
query: request.uri.normalized_query,
|
60
|
-
body: request.body,
|
61
|
-
head: request.headers
|
62
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
63
|
-
writer.reject e
|
64
|
-
requests.shift unless pipeline?
|
65
|
-
return
|
66
|
-
end
|
67
|
-
|
68
|
-
req.callback do
|
69
|
-
requests.shift unless pipeline?
|
70
|
-
|
71
|
-
writer.fulfill Response.new(
|
72
|
-
request,
|
73
|
-
req.last_effective_url,
|
74
|
-
req.response_header.status,
|
75
|
-
req.response_header,
|
76
|
-
req.response,
|
77
|
-
)
|
78
|
-
|
79
|
-
if req.response_header['CONNECTION'] == 'close'
|
80
|
-
@connection = nil
|
81
|
-
@pipeline = false
|
82
|
-
end
|
83
|
-
|
84
|
-
process_next
|
85
|
-
end
|
86
|
-
|
87
|
-
req.errback do
|
88
|
-
requests.shift unless pipeline?
|
89
|
-
@connection = nil
|
90
|
-
|
91
|
-
if pipeline?
|
92
|
-
EventMachine.next_tick do
|
93
|
-
@pipeline = false
|
94
|
-
call request, writer
|
95
|
-
end
|
96
|
-
elsif !retried
|
97
|
-
EventMachine.next_tick { call request, writer }
|
98
|
-
else
|
99
|
-
begin
|
100
|
-
raise "(#{req.response_header.status}) #{req.error}"
|
101
|
-
rescue StandardError => e
|
102
|
-
writer.reject e
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def call_native(request, writer)
|
110
|
-
next_tick do
|
111
|
-
Connection.open(request.uri).call(request, writer)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
private
|
116
|
-
|
117
|
-
def next_tick(&block)
|
118
|
-
ensure_running
|
119
|
-
EventMachine.next_tick(&block)
|
120
|
-
end
|
121
|
-
|
122
|
-
def ensure_running
|
123
|
-
return if EventMachine.reactor_running?
|
124
|
-
|
125
|
-
Thread.new do
|
126
|
-
EventMachine.run
|
127
|
-
rescue StandardError => e
|
128
|
-
puts "#{self.class} -> #{e}\n#{e.backtrace.join("\n")}"
|
129
|
-
raise e
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
@@ -1,269 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'eventmachine'
|
4
|
-
require 'em-http-request'
|
5
|
-
|
6
|
-
module Restify
|
7
|
-
module Adapter
|
8
|
-
class PooledEM < Base
|
9
|
-
include Logging
|
10
|
-
|
11
|
-
# This class maintains a pool of connection objects, grouped by origin,
|
12
|
-
# and ensures limits for total parallel requests and per-origin requests.
|
13
|
-
#
|
14
|
-
# It does so by maintaining a list of already open, reusable connections.
|
15
|
-
# When any of them are checked out for usage, it counts the usages to
|
16
|
-
# prevent constraints being broken.
|
17
|
-
class Pool
|
18
|
-
include Logging
|
19
|
-
|
20
|
-
def initialize(size: 32, per_host: 6, connect_timeout: 2, inactivity_timeout: 10)
|
21
|
-
@size = size
|
22
|
-
@per_host = per_host
|
23
|
-
@connect_timeout = connect_timeout
|
24
|
-
@inactivity_timeout = inactivity_timeout
|
25
|
-
|
26
|
-
@host = Hash.new {|h, k| h[k] = 0 }
|
27
|
-
@available = []
|
28
|
-
@queue = []
|
29
|
-
@used = 0
|
30
|
-
end
|
31
|
-
|
32
|
-
# Request a connection from the pool.
|
33
|
-
#
|
34
|
-
# Attempts to checkout a reusable connection from the pool (or create a
|
35
|
-
# new one). If any of the limits have been reached, the request will be
|
36
|
-
# put onto a queue until other connections are released.
|
37
|
-
#
|
38
|
-
# Returns a Deferrable that succeeds with a connection instance once a
|
39
|
-
# connection has been checked out (usually immediately).
|
40
|
-
#
|
41
|
-
# @return [Deferrable<Request>]
|
42
|
-
#
|
43
|
-
def get(request, timeout: 2)
|
44
|
-
defer = Deferrable.new(request)
|
45
|
-
defer.timeout(timeout, :timeout)
|
46
|
-
defer.errback { @queue.delete(defer) }
|
47
|
-
|
48
|
-
checkout(defer)
|
49
|
-
|
50
|
-
defer
|
51
|
-
end
|
52
|
-
|
53
|
-
# Return a connection to the pool.
|
54
|
-
#
|
55
|
-
# If there are requests in the queue (due to one of the limits having
|
56
|
-
# been reached), they will be given an attempt to use the released
|
57
|
-
# connection.
|
58
|
-
#
|
59
|
-
# If no requests are queued, the connection will be held for reuse by a
|
60
|
-
# subsequent request.
|
61
|
-
#
|
62
|
-
# @return [void]
|
63
|
-
#
|
64
|
-
def release(conn)
|
65
|
-
@available.unshift(conn) if @available.size < @size
|
66
|
-
@used -= 1 if @used.positive?
|
67
|
-
|
68
|
-
logger.debug do
|
69
|
-
"[#{conn.uri}] Released to pool (#{@available.size}/#{@used}/#{size})"
|
70
|
-
end
|
71
|
-
|
72
|
-
checkout(@queue.shift) if @queue.any? # checkout next waiting defer
|
73
|
-
end
|
74
|
-
|
75
|
-
alias << release
|
76
|
-
|
77
|
-
def remove(conn)
|
78
|
-
close(conn)
|
79
|
-
|
80
|
-
logger.debug do
|
81
|
-
"[#{conn.uri}] Removed from pool (#{@available.size}/#{@used}/#{size})"
|
82
|
-
end
|
83
|
-
|
84
|
-
checkout(@queue.shift) if @queue.any? # checkout next waiting defer
|
85
|
-
end
|
86
|
-
|
87
|
-
# Determine the number of connections in the pool.
|
88
|
-
#
|
89
|
-
# This takes into account both reusable (idle) and used connections.
|
90
|
-
#
|
91
|
-
# @return [Integer]
|
92
|
-
#
|
93
|
-
def size
|
94
|
-
@available.size + @used
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def close(conn)
|
100
|
-
@used -= 1 if @used.positive?
|
101
|
-
@host[conn.uri.to_s] -= 1
|
102
|
-
|
103
|
-
conn.close
|
104
|
-
end
|
105
|
-
|
106
|
-
def checkout(defer)
|
107
|
-
origin = defer.request.uri.origin
|
108
|
-
|
109
|
-
if (index = find_reusable_connection(origin))
|
110
|
-
defer.succeed reuse_connection(index, origin)
|
111
|
-
elsif can_build_new_connection?(origin)
|
112
|
-
defer.succeed new_connection(origin)
|
113
|
-
else
|
114
|
-
queue defer
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def find_reusable_connection(origin)
|
119
|
-
@available.find_index {|conn| conn.uri == origin }
|
120
|
-
end
|
121
|
-
|
122
|
-
def reuse_connection(index, origin)
|
123
|
-
@used += 1
|
124
|
-
@available.delete_at(index).tap do
|
125
|
-
logger.debug do
|
126
|
-
"[#{origin}] Take connection from pool " \
|
127
|
-
"(#{@available.size}/#{@used}/#{size})"
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def new_connection(origin)
|
133
|
-
# If we have reached the limit, we have to throw away the oldest
|
134
|
-
# reusable connection in order to open a new one
|
135
|
-
close_oldest if size >= @size
|
136
|
-
|
137
|
-
@used += 1
|
138
|
-
new(origin).tap do
|
139
|
-
logger.debug do
|
140
|
-
"[#{origin}] Add new connection to pool " \
|
141
|
-
"(#{@available.size}/#{@used}/#{size})"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def close_oldest
|
147
|
-
close(@available.pop)
|
148
|
-
|
149
|
-
logger.debug do
|
150
|
-
"[#{origin}] Closed oldest connection in pool " \
|
151
|
-
"(#{@available.size}/#{@used}/#{size})"
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def queue(defer)
|
156
|
-
logger.debug do
|
157
|
-
"[#{origin}] Wait for free slot " \
|
158
|
-
"(#{@available.size}/#{@used}/#{size})"
|
159
|
-
end
|
160
|
-
|
161
|
-
@queue << defer
|
162
|
-
end
|
163
|
-
|
164
|
-
def new(origin)
|
165
|
-
logger.debug do
|
166
|
-
"Connect to '#{origin}' " \
|
167
|
-
"(#{@connect_timeout}/#{@inactivity_timeout})..."
|
168
|
-
end
|
169
|
-
|
170
|
-
@host[origin] += 1
|
171
|
-
|
172
|
-
EventMachine::HttpRequest.new origin,
|
173
|
-
connect_timeout: @connect_timeout,
|
174
|
-
inactivity_timeout: @inactivity_timeout
|
175
|
-
end
|
176
|
-
|
177
|
-
def can_build_new_connection?(origin)
|
178
|
-
return false if @host[origin] >= @per_host
|
179
|
-
|
180
|
-
size < @size || @available.any?
|
181
|
-
end
|
182
|
-
|
183
|
-
class Deferrable
|
184
|
-
include ::EventMachine::Deferrable
|
185
|
-
|
186
|
-
attr_reader :request
|
187
|
-
|
188
|
-
def initialize(request)
|
189
|
-
@request = request
|
190
|
-
end
|
191
|
-
|
192
|
-
def succeed(connection)
|
193
|
-
@connection = connection
|
194
|
-
super
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def initialize(**kwargs)
|
200
|
-
super()
|
201
|
-
@pool = Pool.new(**kwargs)
|
202
|
-
end
|
203
|
-
|
204
|
-
# rubocop:disable Metrics/BlockLength
|
205
|
-
def call_native(request, writer)
|
206
|
-
next_tick do
|
207
|
-
defer = @pool.get(request)
|
208
|
-
|
209
|
-
defer.errback do |error|
|
210
|
-
writer.reject(error)
|
211
|
-
end
|
212
|
-
|
213
|
-
defer.callback do |conn|
|
214
|
-
req = conn.send request.method.downcase,
|
215
|
-
keepalive: true,
|
216
|
-
redirects: 3,
|
217
|
-
path: request.uri.normalized_path,
|
218
|
-
query: request.uri.normalized_query,
|
219
|
-
body: request.body,
|
220
|
-
head: request.headers
|
221
|
-
|
222
|
-
req.callback do
|
223
|
-
writer.fulfill Response.new(
|
224
|
-
request,
|
225
|
-
req.last_effective_url,
|
226
|
-
req.response_header.status,
|
227
|
-
req.response_header,
|
228
|
-
req.response,
|
229
|
-
)
|
230
|
-
|
231
|
-
if req.response_header['CONNECTION'] == 'close'
|
232
|
-
@pool.remove(conn)
|
233
|
-
else
|
234
|
-
@pool << conn
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
req.errback do
|
239
|
-
@pool.remove(conn)
|
240
|
-
writer.reject(req.error)
|
241
|
-
end
|
242
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
243
|
-
@pool.remove(conn)
|
244
|
-
writer.reject(e)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
# rubocop:enable all
|
249
|
-
|
250
|
-
private
|
251
|
-
|
252
|
-
def next_tick(&block)
|
253
|
-
ensure_running
|
254
|
-
EventMachine.next_tick(&block)
|
255
|
-
end
|
256
|
-
|
257
|
-
def ensure_running
|
258
|
-
return if EventMachine.reactor_running?
|
259
|
-
|
260
|
-
Thread.new do
|
261
|
-
EventMachine.run
|
262
|
-
rescue StandardError => e
|
263
|
-
logger.error(e)
|
264
|
-
raise e
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|