restify 1.6.0 → 1.7.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 +4 -0
- data/lib/restify.rb +1 -0
- data/lib/restify/error.rb +1 -13
- data/lib/restify/promise.rb +15 -7
- data/lib/restify/timeout.rb +82 -0
- data/lib/restify/version.rb +1 -1
- data/spec/restify/promise_spec.rb +20 -0
- data/spec/restify/timeout_spec.rb +54 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2f418e5e5915c208da950884e753c70e0c6da648978dde9eb75f067ba6feedc
|
4
|
+
data.tar.gz: 98d1d14d29a06ac14ecaf564b0788d7054a7685ddc3126b4c24e80771ab95e86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb15fbef6af84a77badcfea901c83676952359a509e3d7a91a8b46db4d2808fd7f4c552e151d9a2b7ede68b0f46aaca5c33c77f78bd4aaa614d10a04c31862f6
|
7
|
+
data.tar.gz: 858169275d7a141d641cf1ef492692c6546057aaa6c865b1c5277038d417448b12288ac57cdc7a3e26a260b90275c6fe448deb135154ebe48dca95787ebdbf84
|
data/CHANGELOG.md
CHANGED
data/lib/restify.rb
CHANGED
data/lib/restify/error.rb
CHANGED
@@ -3,24 +3,12 @@
|
|
3
3
|
module Restify
|
4
4
|
#
|
5
5
|
|
6
|
-
# A {Timeout} is raised when a request or promise times out.
|
7
|
-
#
|
8
|
-
class Timeout < StandardError
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source)
|
12
|
-
super "Operation with #{source.class} has timed out"
|
13
|
-
|
14
|
-
@source = source
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
6
|
# A {NetworkError} is raised on unusual network exceptions such as
|
19
7
|
# unresolvable hosts or disconnects.
|
20
8
|
#
|
21
9
|
class NetworkError < StandardError
|
22
10
|
attr_reader :request
|
23
|
-
|
11
|
+
|
24
12
|
def initialize(request, message)
|
25
13
|
@request = request
|
26
14
|
super("[#{request.uri}] #{message}")
|
data/lib/restify/promise.rb
CHANGED
@@ -11,8 +11,13 @@ module Restify
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def wait(timeout = nil)
|
14
|
-
|
14
|
+
t = Timeout.new(timeout, self)
|
15
|
+
|
16
|
+
execute(t) if pending?
|
17
|
+
|
15
18
|
super
|
19
|
+
raise t if incomplete?
|
20
|
+
self
|
16
21
|
end
|
17
22
|
|
18
23
|
def then(&block)
|
@@ -26,25 +31,28 @@ module Restify
|
|
26
31
|
protected
|
27
32
|
|
28
33
|
# @!visibility private
|
29
|
-
def ns_execute(
|
34
|
+
def ns_execute(timeout = nil)
|
30
35
|
return unless compare_and_set_state(:processing, :pending)
|
31
36
|
return unless @task || @dependencies.any?
|
32
37
|
|
33
38
|
executor = Concurrent::SafeTaskExecutor.new \
|
34
39
|
method(:ns_exec), rescue_exception: true
|
35
40
|
|
36
|
-
success, value, reason = executor.execute
|
41
|
+
success, value, reason = executor.execute(timeout)
|
37
42
|
|
38
43
|
complete success, value, reason
|
39
44
|
end
|
40
45
|
|
41
46
|
# @!visibility private
|
42
|
-
def ns_exec
|
43
|
-
|
44
|
-
value = @task ? @task.call(*args) : args
|
47
|
+
def ns_exec(timeout = nil)
|
48
|
+
t = Timeout.new(timeout, self)
|
45
49
|
|
46
|
-
|
50
|
+
args = @dependencies.map do |d|
|
51
|
+
t.wait_on!(d)
|
52
|
+
end
|
47
53
|
|
54
|
+
value = @task ? @task.call(*args) : args
|
55
|
+
value = t.wait_on!(value) while value.is_a?(Promise)
|
48
56
|
value
|
49
57
|
end
|
50
58
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hitimes'
|
4
|
+
|
5
|
+
module Restify
|
6
|
+
class Timeout
|
7
|
+
class << self
|
8
|
+
attr_accessor :default_timeout
|
9
|
+
end
|
10
|
+
|
11
|
+
# Default wait timeout of 300 seconds.
|
12
|
+
self.default_timeout = 300
|
13
|
+
|
14
|
+
def initialize(timeout, target = nil)
|
15
|
+
@timeout = parse_timeout(timeout)
|
16
|
+
@target = target
|
17
|
+
|
18
|
+
@interval = ::Hitimes::Interval.new
|
19
|
+
@interval.start
|
20
|
+
end
|
21
|
+
|
22
|
+
def wait_on!(ivar)
|
23
|
+
ivar.value!(wait_interval).tap do
|
24
|
+
raise self unless ivar.complete?
|
25
|
+
end
|
26
|
+
rescue ::Timeout::Error
|
27
|
+
raise self
|
28
|
+
end
|
29
|
+
|
30
|
+
def timeout!
|
31
|
+
raise self if wait_interval <= 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def exception
|
35
|
+
Error.new(@target)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def wait_interval
|
41
|
+
@timeout - @interval.to_f
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_timeout(value)
|
45
|
+
return self.class.default_timeout if value.nil?
|
46
|
+
|
47
|
+
begin
|
48
|
+
value = Float(value)
|
49
|
+
rescue ArgumentError
|
50
|
+
raise ArgumentError.new \
|
51
|
+
"Timeout must be an number but is #{value}"
|
52
|
+
end
|
53
|
+
|
54
|
+
unless value > 0
|
55
|
+
raise ArgumentError.new "Timeout must be > 0 but is #{value.inspect}."
|
56
|
+
end
|
57
|
+
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
class << self
|
62
|
+
def new(timeout, *args)
|
63
|
+
return timeout if timeout.is_a?(self)
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Error < ::Timeout::Error
|
69
|
+
attr_reader :target
|
70
|
+
|
71
|
+
def initialize(target)
|
72
|
+
@target = target
|
73
|
+
|
74
|
+
if @target
|
75
|
+
super "Operation on #{@target} timed out"
|
76
|
+
else
|
77
|
+
super 'Operation timed out'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/restify/version.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Restify::Promise do
|
6
|
+
let(:promise) { described_class.new }
|
7
|
+
|
6
8
|
describe 'factory methods' do
|
7
9
|
describe '#fulfilled' do
|
8
10
|
subject { described_class.fulfilled(fulfill_value) }
|
@@ -162,4 +164,22 @@ describe Restify::Promise do
|
|
162
164
|
end
|
163
165
|
end
|
164
166
|
end
|
167
|
+
|
168
|
+
describe '#wait' do
|
169
|
+
it 'can time out' do
|
170
|
+
expect { promise.wait(0.1) }.to raise_error ::Timeout::Error
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#value' do
|
175
|
+
it 'can time out' do
|
176
|
+
expect { promise.value!(0.1) }.to raise_error ::Timeout::Error
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '#value!' do
|
181
|
+
it 'can time out' do
|
182
|
+
expect { promise.value!(0.1) }.to raise_error ::Timeout::Error
|
183
|
+
end
|
184
|
+
end
|
165
185
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restify::Timeout do
|
6
|
+
let(:timer) { described_class.new(0.2) }
|
7
|
+
|
8
|
+
describe '#timeout!' do
|
9
|
+
context 'before having timed out' do
|
10
|
+
it 'do nothing' do
|
11
|
+
expect { timer.timeout! }.to_not raise_error
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'after having timed out' do
|
16
|
+
it 'calls given block' do
|
17
|
+
expect { timer.timeout! }.to_not raise_error
|
18
|
+
sleep timer.send(:wait_interval)
|
19
|
+
expect { timer.timeout! }.to raise_error ::Restify::Timeout::Error
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#wait_on!' do
|
25
|
+
it 'calls block on IVar timeout' do
|
26
|
+
expect {
|
27
|
+
timer.wait_on!(Concurrent::IVar.new)
|
28
|
+
}.to raise_error ::Restify::Timeout::Error
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'calls block on Promise timeout' do
|
32
|
+
expect {
|
33
|
+
timer.wait_on!(Restify::Promise.new)
|
34
|
+
}.to raise_error ::Restify::Timeout::Error
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does nothing on successful IVar' do
|
38
|
+
expect {
|
39
|
+
Concurrent::IVar.new.tap do |ivar|
|
40
|
+
Thread.new { ivar.set :success }
|
41
|
+
expect(timer.wait_on!(ivar)).to eq :success
|
42
|
+
end
|
43
|
+
}.to_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'does nothing on successful Promise' do
|
47
|
+
expect {
|
48
|
+
Restify::Promise.fulfilled(:success).tap do |p|
|
49
|
+
expect(timer.wait_on!(p)).to eq :success
|
50
|
+
end
|
51
|
+
}.to_not raise_error
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: hitimes
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: bundler
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,6 +182,7 @@ files:
|
|
168
182
|
- lib/restify/request.rb
|
169
183
|
- lib/restify/resource.rb
|
170
184
|
- lib/restify/response.rb
|
185
|
+
- lib/restify/timeout.rb
|
171
186
|
- lib/restify/version.rb
|
172
187
|
- spec/restify/cache_spec.rb
|
173
188
|
- spec/restify/context_spec.rb
|
@@ -181,6 +196,7 @@ files:
|
|
181
196
|
- spec/restify/registry_spec.rb
|
182
197
|
- spec/restify/relation_spec.rb
|
183
198
|
- spec/restify/resource_spec.rb
|
199
|
+
- spec/restify/timeout_spec.rb
|
184
200
|
- spec/restify_spec.rb
|
185
201
|
- spec/spec_helper.rb
|
186
202
|
homepage: https://github.com/jgraichen/restify
|
@@ -220,5 +236,6 @@ test_files:
|
|
220
236
|
- spec/restify/registry_spec.rb
|
221
237
|
- spec/restify/relation_spec.rb
|
222
238
|
- spec/restify/resource_spec.rb
|
239
|
+
- spec/restify/timeout_spec.rb
|
223
240
|
- spec/restify_spec.rb
|
224
241
|
- spec/spec_helper.rb
|