restify 1.15.1 → 2.0.0
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 +102 -15
- data/README.md +23 -31
- data/lib/restify/adapter/base.rb +4 -0
- data/lib/restify/adapter/telemetry.rb +54 -0
- data/lib/restify/adapter/typhoeus.rb +24 -14
- data/lib/restify/context.rb +7 -11
- data/lib/restify/error.rb +2 -2
- data/lib/restify/global.rb +1 -0
- data/lib/restify/link.rb +4 -4
- data/lib/restify/logging.rb +1 -1
- data/lib/restify/processors/base/parsing.rb +5 -24
- 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/resource.rb +1 -1
- data/lib/restify/response.rb +0 -2
- data/lib/restify/timeout.rb +2 -2
- data/lib/restify/version.rb +4 -4
- data/lib/restify.rb +0 -1
- data/spec/restify/cache_spec.rb +16 -12
- data/spec/restify/context_spec.rb +15 -7
- data/spec/restify/error_spec.rb +23 -16
- data/spec/restify/features/head_requests_spec.rb +7 -5
- data/spec/restify/features/request_bodies_spec.rb +14 -13
- data/spec/restify/features/request_errors_spec.rb +2 -2
- data/spec/restify/features/request_headers_spec.rb +11 -14
- data/spec/restify/features/response_errors_spec.rb +2 -2
- data/spec/restify/global_spec.rb +13 -13
- data/spec/restify/link_spec.rb +9 -9
- data/spec/restify/processors/base_spec.rb +7 -7
- data/spec/restify/processors/json_spec.rb +22 -62
- data/spec/restify/processors/msgpack_spec.rb +40 -76
- data/spec/restify/promise_spec.rb +38 -34
- data/spec/restify/registry_spec.rb +6 -8
- data/spec/restify/relation_spec.rb +196 -17
- data/spec/restify/resource_spec.rb +55 -60
- data/spec/restify/timeout_spec.rb +7 -7
- data/spec/restify_spec.rb +13 -74
- data/spec/spec_helper.rb +13 -17
- data/spec/support/stub_server.rb +3 -3
- metadata +35 -65
- data/lib/restify/adapter/em.rb +0 -139
- data/lib/restify/adapter/pooled_em.rb +0 -270
@@ -8,15 +8,15 @@ describe Restify::Timeout do
|
|
8
8
|
describe '#timeout!' do
|
9
9
|
context 'before having timed out' do
|
10
10
|
it 'do nothing' do
|
11
|
-
expect { timer.timeout! }.
|
11
|
+
expect { timer.timeout! }.not_to raise_error
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
context 'after having timed out' do
|
16
16
|
it 'calls given block' do
|
17
|
-
expect { timer.timeout! }.
|
17
|
+
expect { timer.timeout! }.not_to raise_error
|
18
18
|
sleep timer.send(:wait_interval)
|
19
|
-
expect { timer.timeout! }.to raise_error
|
19
|
+
expect { timer.timeout! }.to raise_error Restify::Timeout::Error
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -25,13 +25,13 @@ describe Restify::Timeout do
|
|
25
25
|
it 'calls block on IVar timeout' do
|
26
26
|
expect do
|
27
27
|
timer.wait_on!(Concurrent::IVar.new)
|
28
|
-
end.to raise_error
|
28
|
+
end.to raise_error Restify::Timeout::Error
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'calls block on Promise timeout' do
|
32
32
|
expect do
|
33
33
|
timer.wait_on!(Restify::Promise.new)
|
34
|
-
end.to raise_error
|
34
|
+
end.to raise_error Restify::Timeout::Error
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'does nothing on successful IVar' do
|
@@ -40,7 +40,7 @@ describe Restify::Timeout do
|
|
40
40
|
Thread.new { ivar.set :success }
|
41
41
|
expect(timer.wait_on!(ivar)).to eq :success
|
42
42
|
end
|
43
|
-
end.
|
43
|
+
end.not_to raise_error
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'does nothing on successful Promise' do
|
@@ -48,7 +48,7 @@ describe Restify::Timeout do
|
|
48
48
|
Restify::Promise.fulfilled(:success).tap do |p|
|
49
49
|
expect(timer.wait_on!(p)).to eq :success
|
50
50
|
end
|
51
|
-
end.
|
51
|
+
end.not_to raise_error
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/spec/restify_spec.rb
CHANGED
@@ -97,7 +97,7 @@ describe Restify do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
context 'within threads' do
|
100
|
-
it '
|
100
|
+
it 'consumes the API' do
|
101
101
|
# Let's get all users
|
102
102
|
|
103
103
|
# First request the entry resource usually the
|
@@ -132,21 +132,21 @@ describe Restify do
|
|
132
132
|
# Because we forgot to send a "name" the server complains
|
133
133
|
# with an error code that will lead to a raised error.
|
134
134
|
|
135
|
-
expect(e.status).to eq :
|
135
|
+
expect(e.status).to eq :unprocessable_content
|
136
136
|
expect(e.code).to eq 422
|
137
137
|
expect(e.errors).to eq 'name' => ["can't be blank"]
|
138
138
|
end
|
139
139
|
|
140
140
|
# Let's try again.
|
141
|
-
created_user = users_relation.post(name: 'John Smith').value!
|
141
|
+
created_user = users_relation.post({name: 'John Smith'}).value!
|
142
142
|
|
143
143
|
# The server returns a 201 Created response with the created
|
144
144
|
# resource.
|
145
145
|
expect(created_user.response.status).to eq :created
|
146
146
|
expect(created_user.response.code).to eq 201
|
147
147
|
|
148
|
-
expect(created_user).to have_key
|
149
|
-
expect(created_user
|
148
|
+
expect(created_user).to have_key 'name'
|
149
|
+
expect(created_user['name']).to eq 'John Smith'
|
150
150
|
|
151
151
|
# Let's follow the "Location" header.
|
152
152
|
followed_resource = created_user.follow.get.value!
|
@@ -154,8 +154,8 @@ describe Restify do
|
|
154
154
|
expect(followed_resource.response.status).to eq :ok
|
155
155
|
expect(followed_resource.response.code).to eq 200
|
156
156
|
|
157
|
-
expect(followed_resource).to have_key
|
158
|
-
expect(followed_resource
|
157
|
+
expect(followed_resource).to have_key 'name'
|
158
|
+
expect(followed_resource['name']).to eq 'John Smith'
|
159
159
|
|
160
160
|
# Now we will fetch a list of all users.
|
161
161
|
users = users_relation.get.value!
|
@@ -168,80 +168,19 @@ describe Restify do
|
|
168
168
|
|
169
169
|
# We have all our attributes and relations here as defined in the
|
170
170
|
# responses from the server.
|
171
|
-
expect(user).to have_key
|
172
|
-
expect(user[
|
171
|
+
expect(user).to have_key 'name'
|
172
|
+
expect(user['name']).to eq 'John Smith'
|
173
173
|
expect(user).to have_relation :self
|
174
174
|
expect(user).to have_relation :blurb
|
175
175
|
|
176
176
|
# Let's get the blurb.
|
177
177
|
blurb = user.rel(:blurb).get.value!
|
178
178
|
|
179
|
-
expect(blurb).to have_key
|
180
|
-
expect(blurb).to have_key
|
179
|
+
expect(blurb).to have_key 'title'
|
180
|
+
expect(blurb).to have_key 'image'
|
181
181
|
|
182
|
-
expect(blurb[
|
183
|
-
expect(blurb[
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
context 'within EM-synchrony' do
|
188
|
-
it 'should consume the API' do
|
189
|
-
skip 'Seems to be impossible to detect EM scheduled fibers from within'
|
190
|
-
|
191
|
-
EM.synchrony do
|
192
|
-
root = Restify.new('http://localhost:9292/base').get.value!
|
193
|
-
|
194
|
-
users_relation = root.rel(:users)
|
195
|
-
|
196
|
-
expect(users_relation).to be_a Restify::Relation
|
197
|
-
|
198
|
-
create_user_promise = users_relation.post
|
199
|
-
expect(create_user_promise).to be_a Restify::Promise
|
200
|
-
|
201
|
-
expect { create_user_promise.value! }.to \
|
202
|
-
raise_error(Restify::ClientError) do |e|
|
203
|
-
expect(e.status).to eq :unprocessable_entity
|
204
|
-
expect(e.code).to eq 422
|
205
|
-
expect(e.errors).to eq 'name' => ["can't be blank"]
|
206
|
-
end
|
207
|
-
|
208
|
-
created_user = users_relation.post(name: 'John Smith').value!
|
209
|
-
|
210
|
-
expect(created_user.response.status).to eq :created
|
211
|
-
expect(created_user.response.code).to eq 201
|
212
|
-
|
213
|
-
expect(created_user).to have_key :name
|
214
|
-
expect(created_user.name).to eq 'John Smith'
|
215
|
-
|
216
|
-
followed_resource = created_user.follow.get.value!
|
217
|
-
|
218
|
-
expect(followed_resource.response.status).to eq :ok
|
219
|
-
expect(followed_resource.response.code).to eq 200
|
220
|
-
|
221
|
-
expect(followed_resource).to have_key :name
|
222
|
-
expect(followed_resource.name).to eq 'John Smith'
|
223
|
-
|
224
|
-
users = users_relation.get.value!
|
225
|
-
|
226
|
-
expect(users).to have(2).items
|
227
|
-
|
228
|
-
user = users.first
|
229
|
-
|
230
|
-
expect(user).to have_key :name
|
231
|
-
expect(user[:name]).to eq 'John Smith'
|
232
|
-
expect(user).to have_relation :self
|
233
|
-
expect(user).to have_relation :blurb
|
234
|
-
|
235
|
-
blurb = user.rel(:blurb).get.value!
|
236
|
-
|
237
|
-
expect(blurb).to have_key :title
|
238
|
-
expect(blurb).to have_key :image
|
239
|
-
|
240
|
-
expect(blurb[:title]).to eq 'Prof. Dr. John Smith'
|
241
|
-
expect(blurb[:image]).to eq 'http://example.org/avatar.png'
|
242
|
-
|
243
|
-
EventMachine.stop
|
244
|
-
end
|
182
|
+
expect(blurb['title']).to eq 'Prof. Dr. John Smith'
|
183
|
+
expect(blurb['image']).to eq 'http://example.org/avatar.png'
|
245
184
|
end
|
246
185
|
end
|
247
186
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,25 +4,21 @@ require 'rspec'
|
|
4
4
|
require 'rspec/collection_matchers'
|
5
5
|
|
6
6
|
require 'simplecov'
|
7
|
+
require 'simplecov-cobertura'
|
8
|
+
|
7
9
|
SimpleCov.start do
|
8
10
|
add_filter 'spec'
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
SimpleCov
|
14
|
-
|
13
|
+
SimpleCov.formatters = [
|
14
|
+
SimpleCov::Formatter::HTMLFormatter,
|
15
|
+
SimpleCov::Formatter::CoberturaFormatter,
|
16
|
+
]
|
15
17
|
|
16
18
|
require 'restify'
|
17
19
|
|
18
20
|
if ENV['ADAPTER']
|
19
21
|
case ENV['ADAPTER'].to_s.downcase
|
20
|
-
when 'em'
|
21
|
-
require 'restify/adapter/em'
|
22
|
-
Restify.adapter = Restify::Adapter::EM.new
|
23
|
-
when 'em-pooled'
|
24
|
-
require 'restify/adapter/pooled_em'
|
25
|
-
Restify.adapter = Restify::Adapter::PooledEM.new
|
26
22
|
when 'typhoeus'
|
27
23
|
require 'restify/adapter/typhoeus'
|
28
24
|
Restify.adapter = Restify::Adapter::Typhoeus.new
|
@@ -40,21 +36,21 @@ RSpec.configure do |config|
|
|
40
36
|
config.order = 'random'
|
41
37
|
|
42
38
|
config.before(:suite) do
|
43
|
-
|
39
|
+
Restify::Timeout.default_timeout = 1.0
|
44
40
|
end
|
45
41
|
|
46
|
-
config.before
|
42
|
+
config.before do |example|
|
47
43
|
next unless (adapter = example.metadata[:adapter])
|
48
|
-
next if Restify.adapter.
|
44
|
+
next if Restify.adapter.class.ancestors.map(&:to_s).include?(adapter)
|
49
45
|
|
50
46
|
skip 'Spec not enabled for current adapter'
|
51
47
|
end
|
52
48
|
|
53
|
-
config.before
|
54
|
-
Ethon.logger =
|
49
|
+
config.before do
|
50
|
+
Ethon.logger = Logging.logger[Ethon] if defined?(Ethon)
|
55
51
|
|
56
|
-
|
57
|
-
|
52
|
+
Logging.logger.root.level = :debug
|
53
|
+
Logging.logger.root.add_appenders Logging.appenders.stdout
|
58
54
|
end
|
59
55
|
|
60
56
|
config.warnings = true
|
data/spec/support/stub_server.rb
CHANGED
@@ -17,10 +17,10 @@ module Stub
|
|
17
17
|
#
|
18
18
|
# If no stub is found a special HTTP 599 error code will be returned.
|
19
19
|
class Handler
|
20
|
-
def call(env)
|
20
|
+
def call(env)
|
21
21
|
signature = WebMock::RequestSignature.new(
|
22
22
|
env['REQUEST_METHOD'].downcase,
|
23
|
-
"http://stubserver#{env['REQUEST_URI']}"
|
23
|
+
"http://stubserver#{env['REQUEST_URI']}",
|
24
24
|
)
|
25
25
|
|
26
26
|
# Extract request headers from rack env. Most header should start with
|
@@ -99,7 +99,7 @@ RSpec.configure do |config|
|
|
99
99
|
WebMock.disable!(except: %i[net_http])
|
100
100
|
end
|
101
101
|
|
102
|
-
config.around
|
102
|
+
config.around do |example|
|
103
103
|
example.run
|
104
104
|
WebMock.reset!
|
105
105
|
end
|
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.0
|
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-14 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
@@ -53,83 +52,77 @@ dependencies:
|
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '1.0'
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
55
|
+
name: hitimes
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - ">="
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
- - "<"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '5.0'
|
60
|
+
version: '0'
|
65
61
|
type: :runtime
|
66
62
|
prerelease: false
|
67
63
|
version_requirements: !ruby/object:Gem::Requirement
|
68
64
|
requirements:
|
69
65
|
- - ">="
|
70
66
|
- !ruby/object:Gem::Version
|
71
|
-
version: '
|
72
|
-
- - "<"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '5.0'
|
67
|
+
version: '0'
|
75
68
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
69
|
+
name: logging
|
77
70
|
requirement: !ruby/object:Gem::Requirement
|
78
71
|
requirements:
|
79
|
-
- - "
|
72
|
+
- - "~>"
|
80
73
|
- !ruby/object:Gem::Version
|
81
|
-
version: '0'
|
74
|
+
version: '2.0'
|
82
75
|
type: :runtime
|
83
76
|
prerelease: false
|
84
77
|
version_requirements: !ruby/object:Gem::Requirement
|
85
78
|
requirements:
|
86
|
-
- - "
|
79
|
+
- - "~>"
|
87
80
|
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
81
|
+
version: '2.0'
|
89
82
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
83
|
+
name: msgpack
|
91
84
|
requirement: !ruby/object:Gem::Requirement
|
92
85
|
requirements:
|
93
86
|
- - "~>"
|
94
87
|
- !ruby/object:Gem::Version
|
95
|
-
version: '1.
|
88
|
+
version: '1.2'
|
96
89
|
type: :runtime
|
97
90
|
prerelease: false
|
98
91
|
version_requirements: !ruby/object:Gem::Requirement
|
99
92
|
requirements:
|
100
93
|
- - "~>"
|
101
94
|
- !ruby/object:Gem::Version
|
102
|
-
version: '1.
|
95
|
+
version: '1.2'
|
103
96
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
97
|
+
name: opentelemetry-api
|
105
98
|
requirement: !ruby/object:Gem::Requirement
|
106
99
|
requirements:
|
107
100
|
- - "~>"
|
108
101
|
- !ruby/object:Gem::Version
|
109
|
-
version: '
|
102
|
+
version: '1.0'
|
110
103
|
type: :runtime
|
111
104
|
prerelease: false
|
112
105
|
version_requirements: !ruby/object:Gem::Requirement
|
113
106
|
requirements:
|
114
107
|
- - "~>"
|
115
108
|
- !ruby/object:Gem::Version
|
116
|
-
version: '
|
109
|
+
version: '1.0'
|
117
110
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
111
|
+
name: opentelemetry-common
|
119
112
|
requirement: !ruby/object:Gem::Requirement
|
120
113
|
requirements:
|
121
|
-
- - "
|
114
|
+
- - ">="
|
122
115
|
- !ruby/object:Gem::Version
|
123
|
-
version: '
|
116
|
+
version: '0'
|
124
117
|
type: :runtime
|
125
118
|
prerelease: false
|
126
119
|
version_requirements: !ruby/object:Gem::Requirement
|
127
120
|
requirements:
|
128
|
-
- - "
|
121
|
+
- - ">="
|
129
122
|
- !ruby/object:Gem::Version
|
130
|
-
version: '
|
123
|
+
version: '0'
|
131
124
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
125
|
+
name: rack
|
133
126
|
requirement: !ruby/object:Gem::Requirement
|
134
127
|
requirements:
|
135
128
|
- - ">="
|
@@ -143,23 +136,23 @@ dependencies:
|
|
143
136
|
- !ruby/object:Gem::Version
|
144
137
|
version: '0'
|
145
138
|
- !ruby/object:Gem::Dependency
|
146
|
-
name:
|
139
|
+
name: typhoeus
|
147
140
|
requirement: !ruby/object:Gem::Requirement
|
148
141
|
requirements:
|
149
|
-
- - "
|
142
|
+
- - "~>"
|
150
143
|
- !ruby/object:Gem::Version
|
151
|
-
version: '
|
152
|
-
type: :
|
144
|
+
version: '1.3'
|
145
|
+
type: :runtime
|
153
146
|
prerelease: false
|
154
147
|
version_requirements: !ruby/object:Gem::Requirement
|
155
148
|
requirements:
|
156
|
-
- - "
|
149
|
+
- - "~>"
|
157
150
|
- !ruby/object:Gem::Version
|
158
|
-
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: []
|
@@ -169,8 +162,7 @@ files:
|
|
169
162
|
- README.md
|
170
163
|
- lib/restify.rb
|
171
164
|
- lib/restify/adapter/base.rb
|
172
|
-
- lib/restify/adapter/
|
173
|
-
- lib/restify/adapter/pooled_em.rb
|
165
|
+
- lib/restify/adapter/telemetry.rb
|
174
166
|
- lib/restify/adapter/typhoeus.rb
|
175
167
|
- lib/restify/cache.rb
|
176
168
|
- lib/restify/context.rb
|
@@ -214,8 +206,8 @@ files:
|
|
214
206
|
homepage: https://github.com/jgraichen/restify
|
215
207
|
licenses:
|
216
208
|
- LGPL-3.0+
|
217
|
-
metadata:
|
218
|
-
|
209
|
+
metadata:
|
210
|
+
rubygems_mfa_required: 'true'
|
219
211
|
rdoc_options: []
|
220
212
|
require_paths:
|
221
213
|
- lib
|
@@ -223,36 +215,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
215
|
requirements:
|
224
216
|
- - ">="
|
225
217
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
218
|
+
version: 3.1.0
|
227
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
220
|
requirements:
|
229
221
|
- - ">="
|
230
222
|
- !ruby/object:Gem::Version
|
231
223
|
version: '0'
|
232
224
|
requirements: []
|
233
|
-
rubygems_version: 3.
|
234
|
-
signing_key:
|
225
|
+
rubygems_version: 3.6.2
|
235
226
|
specification_version: 4
|
236
227
|
summary: An experimental hypermedia REST client.
|
237
|
-
test_files:
|
238
|
-
- spec/restify/cache_spec.rb
|
239
|
-
- spec/restify/context_spec.rb
|
240
|
-
- spec/restify/error_spec.rb
|
241
|
-
- spec/restify/features/head_requests_spec.rb
|
242
|
-
- spec/restify/features/request_bodies_spec.rb
|
243
|
-
- spec/restify/features/request_errors_spec.rb
|
244
|
-
- spec/restify/features/request_headers_spec.rb
|
245
|
-
- spec/restify/features/response_errors_spec.rb
|
246
|
-
- spec/restify/global_spec.rb
|
247
|
-
- spec/restify/link_spec.rb
|
248
|
-
- spec/restify/processors/base_spec.rb
|
249
|
-
- spec/restify/processors/json_spec.rb
|
250
|
-
- spec/restify/processors/msgpack_spec.rb
|
251
|
-
- spec/restify/promise_spec.rb
|
252
|
-
- spec/restify/registry_spec.rb
|
253
|
-
- spec/restify/relation_spec.rb
|
254
|
-
- spec/restify/resource_spec.rb
|
255
|
-
- spec/restify/timeout_spec.rb
|
256
|
-
- spec/restify_spec.rb
|
257
|
-
- spec/spec_helper.rb
|
258
|
-
- spec/support/stub_server.rb
|
228
|
+
test_files: []
|
data/lib/restify/adapter/em.rb
DELETED
@@ -1,139 +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
|
-
# rubocop:disable Metrics/AbcSize
|
51
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
52
|
-
# rubocop:disable Metrics/MethodLength
|
53
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
54
|
-
def process_next
|
55
|
-
return if requests.empty?
|
56
|
-
|
57
|
-
request, writer, retried = pipeline? ? requests.shift : requests.first
|
58
|
-
begin
|
59
|
-
req = connection.send request.method.downcase,
|
60
|
-
keepalive: true,
|
61
|
-
redirects: 3,
|
62
|
-
path: request.uri.normalized_path,
|
63
|
-
query: request.uri.normalized_query,
|
64
|
-
body: request.body,
|
65
|
-
head: request.headers
|
66
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
67
|
-
writer.reject e
|
68
|
-
requests.shift unless pipeline?
|
69
|
-
return
|
70
|
-
end
|
71
|
-
|
72
|
-
req.callback do
|
73
|
-
requests.shift unless pipeline?
|
74
|
-
|
75
|
-
writer.fulfill Response.new(
|
76
|
-
request,
|
77
|
-
req.last_effective_url,
|
78
|
-
req.response_header.status,
|
79
|
-
req.response_header,
|
80
|
-
req.response
|
81
|
-
)
|
82
|
-
|
83
|
-
if req.response_header['CONNECTION'] == 'close'
|
84
|
-
@connection = nil
|
85
|
-
@pipeline = false
|
86
|
-
end
|
87
|
-
|
88
|
-
process_next
|
89
|
-
end
|
90
|
-
|
91
|
-
req.errback do
|
92
|
-
requests.shift unless pipeline?
|
93
|
-
@connection = nil
|
94
|
-
|
95
|
-
if pipeline?
|
96
|
-
EventMachine.next_tick do
|
97
|
-
@pipeline = false
|
98
|
-
call request, writer
|
99
|
-
end
|
100
|
-
elsif !retried
|
101
|
-
EventMachine.next_tick { call request, writer }
|
102
|
-
else
|
103
|
-
begin
|
104
|
-
raise "(#{req.response_header.status}) #{req.error}"
|
105
|
-
rescue StandardError => e
|
106
|
-
writer.reject e
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
# rubocop:enable all
|
112
|
-
end
|
113
|
-
|
114
|
-
def call_native(request, writer)
|
115
|
-
next_tick do
|
116
|
-
Connection.open(request.uri).call(request, writer)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def next_tick(&block)
|
123
|
-
ensure_running
|
124
|
-
EventMachine.next_tick(&block)
|
125
|
-
end
|
126
|
-
|
127
|
-
def ensure_running
|
128
|
-
return if EventMachine.reactor_running?
|
129
|
-
|
130
|
-
Thread.new do
|
131
|
-
EventMachine.run {}
|
132
|
-
rescue StandardError => e
|
133
|
-
puts "#{self.class} -> #{e}\n#{e.backtrace.join("\n")}"
|
134
|
-
raise e
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|