much-timeout 0.0.1 → 0.1.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 +5 -5
- data/README.md +77 -2
- data/lib/much-timeout.rb +84 -0
- data/lib/much-timeout/version.rb +1 -1
- data/much-timeout.gemspec +2 -2
- data/test/unit/much-timeout_tests.rb +322 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: bb4cac19b782d0ee31fd1fd5f00134a8aa6945df
|
4
|
-
data.tar.gz: 0da45180c2d2a786d818ef1dfd00a4bd20805bfb
|
5
2
|
SHA512:
|
6
|
-
|
7
|
-
|
3
|
+
data.tar.gz: 2fa361b98af1eaae451ed91a28d1d9641777eab828716d4c10a3411170f0bc6de3dc8f4c3855b368a2e29badcb23f8082b4d4b237fa89af72c4660a585a80263
|
4
|
+
metadata.gz: 265aaee5763dc7fc6d5208ea42ceefb11dc8cfeb5f70173885c0bd0206ff41dcbe405d9c233b2d6948f72e21d6a1fb9506333852be349c81841db08a2a050afd
|
5
|
+
SHA1:
|
6
|
+
data.tar.gz: 0bbfd0ebdc797ec310f8bc33f39e40a51973e4b5
|
7
|
+
metadata.gz: 3239b0fddda2d296afeab424878e399219bf5fa7
|
data/README.md
CHANGED
@@ -1,10 +1,85 @@
|
|
1
1
|
# MuchTimeout
|
2
2
|
|
3
|
-
IO.select based timeouts
|
3
|
+
IO.select based timeouts. This is an alternative to the stdlib's Timeout module that doesn't rely on `sleep`. This should produce more accurate timeouts with an expanded API for different handling options.
|
4
4
|
|
5
5
|
## Usage
|
6
6
|
|
7
|
-
|
7
|
+
### `timeout`
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'much-timeout'
|
11
|
+
|
12
|
+
MuchTimeout.timeout(5) do
|
13
|
+
# ... something that should be interrupted ...
|
14
|
+
|
15
|
+
# raises a `MuchTimeout::TimeoutError` exception if it takes more than 5 seconds
|
16
|
+
# returns the result of the block otherwise
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
MuchTimeout, in its basic form, is a replacement for Timeout. The main difference is that `IO.select` on an internal pipe is the mechanism for detecting the timeout. Another difference is that the block is executed in a separate thread while the select/monitoring occurs in the main thread.
|
21
|
+
|
22
|
+
**Note**: like Timeout, **`Thread#raise` is used to interrupt the block**. This technique is [widely](http://blog.headius.com/2008/02/ruby-threadraise-threadkill-timeoutrb.html) [considered](http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/) to be [dangerous](http://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/). Be aware and use responsibly.
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
MuchTimeout.timeout(5, MyCustomTimeoutError) do
|
26
|
+
# ... something that should be interrupted ...
|
27
|
+
|
28
|
+
# raises a `MyCustomTimeoutError` exception if it takes more than 5 seconds
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
Like Timeout, you can optionally specify a custom exception class to raise.
|
33
|
+
|
34
|
+
### `optional_timeout`
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
seconds = [5, nil].sample
|
38
|
+
MuchTimeout.optional_timeout(seconds) do
|
39
|
+
# ... something that should be interrupted ...
|
40
|
+
|
41
|
+
# raises an exception if seconds is not nil and it takes more than 5 seconds
|
42
|
+
# otherwise the block is called directly and will not be interrupted
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
In addtion to the basic `timeout` API, MuchTimeout provides `optional_timeout` which conditionally applies timeout handling based on the given seconds value. Passing `nil` seconds will just call the block and will not apply any timeout handling (where passing `nil` seconds to `timeout` raises an argument error).
|
47
|
+
|
48
|
+
### `just_{optional_}timeout`
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
MuchTimeout.just_timeout(5, :do => proc{
|
52
|
+
# ... something that should be interrupted ...
|
53
|
+
|
54
|
+
# interrupt if it takes more than 5 seconds
|
55
|
+
# no exceptions are raised (they are all rescued internally)
|
56
|
+
})
|
57
|
+
|
58
|
+
seconds = [5, nil].sample
|
59
|
+
MuchTimeout.just_optional_timeout(seconds, :do => proc{
|
60
|
+
# ... something that should be interrupted ...
|
61
|
+
|
62
|
+
# interrupt if seconds is not nil and it takes more than 5 seconds
|
63
|
+
# no exceptions are raised (they are all rescued internally)
|
64
|
+
})
|
65
|
+
```
|
66
|
+
|
67
|
+
These alternative timeout methods execute and interrupt the given `:do` block if it times out. However, no exceptions are raised and no exception handling is required (the `Thread#raise` interrupt is rescued internally). Use this option to avoid any custom exception handling logic when you don't care about the timeout exception information.
|
68
|
+
|
69
|
+
In the case you want to run some custom logic when a timeout occurs, pass an optional `:on_timeout` proc:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
MuchTimeout.just_timeout(5, {
|
73
|
+
:do => proc{
|
74
|
+
# ... something that should be interrupted ...
|
75
|
+
},
|
76
|
+
:on_timeout => proc{
|
77
|
+
# ... something that should run when a timeout occurs ...
|
78
|
+
}
|
79
|
+
})
|
80
|
+
```
|
81
|
+
|
82
|
+
This works as you'd expect for both `just_timeout` and `just_optional_timeout`.
|
8
83
|
|
9
84
|
## Installation
|
10
85
|
|
data/lib/much-timeout.rb
CHANGED
@@ -1,4 +1,88 @@
|
|
1
|
+
require 'thread'
|
1
2
|
require "much-timeout/version"
|
2
3
|
|
3
4
|
module MuchTimeout
|
5
|
+
|
6
|
+
TimeoutError = Class.new(Interrupt)
|
7
|
+
|
8
|
+
PIPE_SIGNAL = '.'
|
9
|
+
|
10
|
+
def self.timeout(seconds, klass = nil, &block)
|
11
|
+
if seconds.nil?
|
12
|
+
raise ArgumentError, 'please specify a non-nil seconds value'
|
13
|
+
end
|
14
|
+
if !seconds.kind_of?(::Numeric)
|
15
|
+
raise ArgumentError, "please specify a numeric seconds value " \
|
16
|
+
"(`#{seconds.inspect}` was given)"
|
17
|
+
end
|
18
|
+
exception_klass = klass || TimeoutError
|
19
|
+
reader, writer = IO.pipe
|
20
|
+
|
21
|
+
begin
|
22
|
+
block_thread ||= Thread.new do
|
23
|
+
begin
|
24
|
+
block.call
|
25
|
+
ensure
|
26
|
+
writer.write_nonblock(PIPE_SIGNAL) rescue false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if !!::IO.select([reader], nil, nil, seconds)
|
30
|
+
block_thread.join
|
31
|
+
else
|
32
|
+
block_thread.raise exception_klass
|
33
|
+
block_thread.join
|
34
|
+
end
|
35
|
+
block_thread.value
|
36
|
+
ensure
|
37
|
+
reader.close rescue false
|
38
|
+
writer.close rescue false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.optional_timeout(seconds, klass = nil, &block)
|
43
|
+
if !seconds.nil?
|
44
|
+
self.timeout(seconds, klass, &block)
|
45
|
+
else
|
46
|
+
block.call
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.just_timeout(seconds, args)
|
51
|
+
args ||= {}
|
52
|
+
if args[:do].nil?
|
53
|
+
raise ArgumentError, 'you need to specify a :do block arg to call'
|
54
|
+
end
|
55
|
+
if !args[:do].kind_of?(::Proc)
|
56
|
+
raise ArgumentError, "you need pass a Proc as the :do arg " \
|
57
|
+
"(`#{args[:do].inspect}` was given)"
|
58
|
+
end
|
59
|
+
if !args[:on_timeout].nil? && !args[:on_timeout].kind_of?(::Proc)
|
60
|
+
raise ArgumentError, "you need pass a Proc as the :on_timeout arg " \
|
61
|
+
"(`#{args[:on_timeout].inspect}` was given)"
|
62
|
+
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
self.timeout(seconds, &args[:do])
|
66
|
+
rescue TimeoutError
|
67
|
+
(args[:on_timeout] || proc{ }).call
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.just_optional_timeout(seconds, args)
|
72
|
+
args ||= {}
|
73
|
+
if args[:do].nil?
|
74
|
+
raise ArgumentError, 'you need to specify a :do block arg to call'
|
75
|
+
end
|
76
|
+
if !args[:do].kind_of?(::Proc)
|
77
|
+
raise ArgumentError, "you need pass a Proc as the :do arg " \
|
78
|
+
"(`#{args[:do].inspect}` was given)"
|
79
|
+
end
|
80
|
+
|
81
|
+
if !seconds.nil?
|
82
|
+
self.just_timeout(seconds, args)
|
83
|
+
else
|
84
|
+
args[:do].call
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
4
88
|
end
|
data/lib/much-timeout/version.rb
CHANGED
data/much-timeout.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = MuchTimeout::VERSION
|
9
9
|
gem.authors = ["Kelly Redding", "Collin Redding"]
|
10
10
|
gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
|
11
|
-
gem.summary = "IO.select based timeouts"
|
12
|
-
gem.description = "IO.select based timeouts"
|
11
|
+
gem.summary = "IO.select based timeouts; an alternative to Ruby's stdlib Timeout module."
|
12
|
+
gem.description = "IO.select based timeouts; an alternative to Ruby's stdlib Timeout module."
|
13
13
|
gem.homepage = "http://github.com/redding/much-timeout"
|
14
14
|
gem.license = 'MIT'
|
15
15
|
|
@@ -0,0 +1,322 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'much-timeout'
|
3
|
+
|
4
|
+
module MuchTimeout
|
5
|
+
|
6
|
+
class UnitTests < Assert::Context
|
7
|
+
desc "MuchTimeout"
|
8
|
+
setup do
|
9
|
+
@module = MuchTimeout
|
10
|
+
end
|
11
|
+
subject{ @module }
|
12
|
+
|
13
|
+
should have_imeths :timeout, :optional_timeout
|
14
|
+
should have_imeths :just_timeout, :just_optional_timeout
|
15
|
+
|
16
|
+
should "know its TimeoutError" do
|
17
|
+
assert_true subject::TimeoutError < Interrupt
|
18
|
+
end
|
19
|
+
|
20
|
+
should "know its pipe signal" do
|
21
|
+
assert_equal '.', subject::PIPE_SIGNAL
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class TimeoutSetupTests < UnitTests
|
27
|
+
setup do
|
28
|
+
@mutex = Mutex.new
|
29
|
+
@cond_var = ConditionVariable.new
|
30
|
+
@seconds = 0.01
|
31
|
+
@exception = Class.new(RuntimeError)
|
32
|
+
@return_val = Factory.string
|
33
|
+
end
|
34
|
+
teardown do
|
35
|
+
@cond_var.broadcast
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class TimeoutTests < TimeoutSetupTests
|
41
|
+
desc "`timeout` method"
|
42
|
+
|
43
|
+
should "interrupt and raise if the block takes too long to run" do
|
44
|
+
assert_raises(TimeoutError) do
|
45
|
+
subject.timeout(@seconds) do
|
46
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
should "interrupt and raise if a custom exception is given and block times out" do
|
52
|
+
assert_raises(@exception) do
|
53
|
+
subject.timeout(@seconds, @exception) do
|
54
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
should "not interrupt and return the block's return value if there is no timeout" do
|
60
|
+
val = nil
|
61
|
+
assert_nothing_raised do
|
62
|
+
val = subject.timeout(@seconds){ @return_val }
|
63
|
+
end
|
64
|
+
assert_equal @return_val, val
|
65
|
+
end
|
66
|
+
|
67
|
+
should "raise any exception that the block raises" do
|
68
|
+
assert_raises(@exception) do
|
69
|
+
subject.timeout(@seconds){ raise @exception }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
should "complain if given a nil seconds value" do
|
74
|
+
assert_raises(ArgumentError) do
|
75
|
+
subject.timeout(nil){ }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
should "complain if given a non-numeric seconds value" do
|
80
|
+
assert_raises(ArgumentError) do
|
81
|
+
subject.timeout(Factory.string){ }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
class OptionalTimeoutTests < TimeoutSetupTests
|
88
|
+
desc "`optional_timeout` method"
|
89
|
+
|
90
|
+
should "call `timeout` with any given args if seconds is not nil" do
|
91
|
+
# this repeats the relevent tests from the TimeoutTests above
|
92
|
+
|
93
|
+
assert_raises(TimeoutError) do
|
94
|
+
subject.optional_timeout(@seconds) do
|
95
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
assert_raises(@exception) do
|
100
|
+
subject.optional_timeout(@seconds, @exception) do
|
101
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
val = nil
|
106
|
+
assert_nothing_raised do
|
107
|
+
val = subject.optional_timeout(@seconds){ @return_val }
|
108
|
+
end
|
109
|
+
assert_equal @return_val, val
|
110
|
+
|
111
|
+
assert_raises(@exception) do
|
112
|
+
subject.optional_timeout(@seconds){ raise @exception }
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_raises(ArgumentError) do
|
116
|
+
subject.optional_timeout(Factory.string){ }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
should "call the given block directly if seconds is nil" do
|
121
|
+
val = nil
|
122
|
+
assert_nothing_raised do
|
123
|
+
val = subject.optional_timeout(nil){ sleep @seconds; @return_val }
|
124
|
+
end
|
125
|
+
assert_equal @return_val, val
|
126
|
+
|
127
|
+
assert_raises(@exception) do
|
128
|
+
subject.optional_timeout(nil){ raise @exception }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
class JustTimeoutTests < TimeoutSetupTests
|
135
|
+
desc "`just_timeout` method"
|
136
|
+
setup do
|
137
|
+
@val_set = nil
|
138
|
+
end
|
139
|
+
|
140
|
+
should "call `timeout` with the given seconds and :do arg" do
|
141
|
+
# this repeats the relevent tests from the TimeoutTests above
|
142
|
+
|
143
|
+
assert_nothing_raised do
|
144
|
+
subject.just_timeout(@seconds, :do => proc{
|
145
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
146
|
+
@val_set = Factory.string
|
147
|
+
})
|
148
|
+
end
|
149
|
+
assert_nil @val_set
|
150
|
+
|
151
|
+
val = nil
|
152
|
+
assert_nothing_raised do
|
153
|
+
val = subject.just_timeout(@seconds, :do => proc{ @return_val })
|
154
|
+
end
|
155
|
+
assert_equal @return_val, val
|
156
|
+
|
157
|
+
assert_raises(@exception) do
|
158
|
+
subject.just_timeout(@seconds, :do => proc{ raise @exception })
|
159
|
+
end
|
160
|
+
|
161
|
+
assert_raises(ArgumentError) do
|
162
|
+
subject.just_timeout(nil, :do => proc{ })
|
163
|
+
end
|
164
|
+
|
165
|
+
assert_raises(ArgumentError) do
|
166
|
+
subject.just_timeout(Factory.string, :do => proc{ })
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
should "call any given :on_timeout arg if a timeout occurs" do
|
171
|
+
exp = Factory.string
|
172
|
+
assert_nothing_raised do
|
173
|
+
subject.just_timeout(@seconds, {
|
174
|
+
:do => proc{
|
175
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
176
|
+
},
|
177
|
+
:on_timeout => proc{ @val_set = exp }
|
178
|
+
})
|
179
|
+
end
|
180
|
+
assert_equal exp, @val_set
|
181
|
+
|
182
|
+
@val_set = val = nil
|
183
|
+
assert_nothing_raised do
|
184
|
+
val = subject.just_timeout(@seconds, {
|
185
|
+
:do => proc{ @return_val },
|
186
|
+
:on_timeout => proc{ @val_set = exp }
|
187
|
+
})
|
188
|
+
end
|
189
|
+
assert_equal @return_val, val
|
190
|
+
assert_nil @val_set
|
191
|
+
end
|
192
|
+
|
193
|
+
should "complain if not given a :do arg" do
|
194
|
+
assert_raises(ArgumentError) do
|
195
|
+
subject.just_timeout(@seconds){ }
|
196
|
+
end
|
197
|
+
assert_raises(ArgumentError) do
|
198
|
+
subject.just_timeout(@seconds, :do => nil)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
should "complain if given a non-proc :do arg" do
|
203
|
+
assert_raises(ArgumentError) do
|
204
|
+
subject.just_timeout(@seconds, :do => Factory.string)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
should "complain if given a non-proc :on_timeout arg" do
|
209
|
+
assert_raises(ArgumentError) do
|
210
|
+
subject.just_timeout(@seconds, {
|
211
|
+
:do => proc{ },
|
212
|
+
:on_timeout => Factory.string
|
213
|
+
})
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
class JustOptionalTimeoutTests < TimeoutSetupTests
|
220
|
+
desc "`just_optional_timeout` method"
|
221
|
+
setup do
|
222
|
+
@val_set = nil
|
223
|
+
end
|
224
|
+
|
225
|
+
should "call `optional_timeout` with the given seconds and :do arg" do
|
226
|
+
# this repeats the relevent tests from the JustTimeoutTests above
|
227
|
+
|
228
|
+
assert_nothing_raised do
|
229
|
+
subject.just_optional_timeout(@seconds, :do => proc{
|
230
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
231
|
+
@val_set = Factory.string
|
232
|
+
})
|
233
|
+
end
|
234
|
+
assert_nil @val_set
|
235
|
+
|
236
|
+
val = nil
|
237
|
+
assert_nothing_raised do
|
238
|
+
val = subject.just_optional_timeout(@seconds, :do => proc{ @return_val })
|
239
|
+
end
|
240
|
+
assert_equal @return_val, val
|
241
|
+
|
242
|
+
assert_raises(@exception) do
|
243
|
+
subject.just_optional_timeout(@seconds, :do => proc{ raise @exception })
|
244
|
+
end
|
245
|
+
|
246
|
+
assert_raises(ArgumentError) do
|
247
|
+
subject.just_optional_timeout(Factory.string, :do => proc{ })
|
248
|
+
end
|
249
|
+
|
250
|
+
exp = Factory.string
|
251
|
+
assert_nothing_raised do
|
252
|
+
subject.just_optional_timeout(@seconds, {
|
253
|
+
:do => proc{
|
254
|
+
@mutex.synchronize{ @cond_var.wait(@mutex) }
|
255
|
+
},
|
256
|
+
:on_timeout => proc{ @val_set = exp }
|
257
|
+
})
|
258
|
+
end
|
259
|
+
assert_equal exp, @val_set
|
260
|
+
|
261
|
+
@val_set = val = nil
|
262
|
+
assert_nothing_raised do
|
263
|
+
val = subject.just_optional_timeout(@seconds, {
|
264
|
+
:do => proc{ @return_val },
|
265
|
+
:on_timeout => proc{ @val_set = exp }
|
266
|
+
})
|
267
|
+
end
|
268
|
+
assert_equal @return_val, val
|
269
|
+
assert_nil @val_set
|
270
|
+
|
271
|
+
assert_raises(ArgumentError) do
|
272
|
+
subject.just_optional_timeout(@seconds){ }
|
273
|
+
end
|
274
|
+
assert_raises(ArgumentError) do
|
275
|
+
subject.just_optional_timeout(@seconds, :do => nil)
|
276
|
+
end
|
277
|
+
|
278
|
+
assert_raises(ArgumentError) do
|
279
|
+
subject.just_optional_timeout(@seconds, :do => Factory.string)
|
280
|
+
end
|
281
|
+
|
282
|
+
assert_raises(ArgumentError) do
|
283
|
+
subject.just_optional_timeout(@seconds, {
|
284
|
+
:do => proc{ },
|
285
|
+
:on_timeout => Factory.string
|
286
|
+
})
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
should "call the given :do arg directly if seconds is nil" do
|
291
|
+
val = nil
|
292
|
+
assert_nothing_raised do
|
293
|
+
val = subject.just_optional_timeout(nil, :do => proc{
|
294
|
+
sleep @seconds
|
295
|
+
@return_val
|
296
|
+
})
|
297
|
+
end
|
298
|
+
assert_equal @return_val, val
|
299
|
+
|
300
|
+
assert_raises(@exception) do
|
301
|
+
subject.just_optional_timeout(nil, :do => proc{ raise @exception })
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
should "complain if not given a :do arg" do
|
306
|
+
assert_raises(ArgumentError) do
|
307
|
+
subject.just_optional_timeout([@seconds, nil].sample){ }
|
308
|
+
end
|
309
|
+
assert_raises(ArgumentError) do
|
310
|
+
subject.just_optional_timeout([@seconds, nil].sample, :do => nil)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
should "complain if given a non-proc :do arg" do
|
315
|
+
assert_raises(ArgumentError) do
|
316
|
+
subject.just_optional_timeout([@seconds, nil].sample, :do => Factory.string)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: much-timeout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kelly Redding
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2016-06-
|
13
|
+
date: 2016-06-07 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: assert
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
version: 2.16.1
|
23
23
|
type: :development
|
24
24
|
version_requirements: *id001
|
25
|
-
description: IO.select based timeouts
|
25
|
+
description: IO.select based timeouts; an alternative to Ruby's stdlib Timeout module.
|
26
26
|
email:
|
27
27
|
- kelly@kellyredding.com
|
28
28
|
- collin.redding@me.com
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- much-timeout.gemspec
|
44
44
|
- test/helper.rb
|
45
45
|
- test/support/factory.rb
|
46
|
+
- test/unit/much-timeout_tests.rb
|
46
47
|
- tmp/.gitkeep
|
47
48
|
homepage: http://github.com/redding/much-timeout
|
48
49
|
licenses:
|
@@ -69,7 +70,8 @@ rubyforge_project:
|
|
69
70
|
rubygems_version: 2.6.4
|
70
71
|
signing_key:
|
71
72
|
specification_version: 4
|
72
|
-
summary: IO.select based timeouts
|
73
|
+
summary: IO.select based timeouts; an alternative to Ruby's stdlib Timeout module.
|
73
74
|
test_files:
|
74
75
|
- test/helper.rb
|
75
76
|
- test/support/factory.rb
|
77
|
+
- test/unit/much-timeout_tests.rb
|