restify 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|