async 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e95eca0cff51fba91c446924485001f6bd9d63978d92a15b583bbb8916b7c53b
4
- data.tar.gz: 463002c552022842360fb031aee28c6286ed7af44761e3e8e55b60c40f1094bb
3
+ metadata.gz: 3722acb6246ee95cecd02b7d763cf695eabe3726510d2eda756ecfe3e809632e
4
+ data.tar.gz: da8e9cd294faf48293c39f7577ef6b807d3e46881fb99f248a7d3369bbc2d182
5
5
  SHA512:
6
- metadata.gz: 8d2848633ef85c07e88321c1cc5f4eb890fc53eb66c973dcf182ab5b535fa211b3493d1a265500c83a359bcd673912ea9b77a076e0c818add4ad82b7d5b35a11
7
- data.tar.gz: 9814c99bbdb06a4993aefd573cf77795d813ee0f129d93cd7df1cc29522cd4f2b11b212a4d9c91d45bdd9f78114ee21ca55dac0fa51438a877124e08e69dd382
6
+ metadata.gz: b69666de33bf4b97a4b72a9b9e6ecce98651dbc7fc6eab8c124946f979731fdb3b349d3143b6763a5cf2a41b2a2725d8186d3d2903603667dbd5ac973aea7686
7
+ data.tar.gz: 3e5a5211537c71bc368aeb7b1d7396693ad6f8908bdbf8e20a5a3baf395a0bb908eddbab2e05f3293667c3e25b2b75d08909df7dc6540d47522f411361ff9628
data/README.md CHANGED
@@ -270,7 +270,7 @@ You can wrap asynchronous operations in a timeout. This ensures that malicious s
270
270
  require 'async'
271
271
 
272
272
  Async do |task|
273
- task.timeout(1) do
273
+ task.with_timeout(1) do
274
274
  task.sleep 100
275
275
  rescue Async::TimeoutError
276
276
  puts "I timed out!"
@@ -13,7 +13,7 @@ class IO
13
13
 
14
14
  monitor = reactor.add_io(fiber, descriptor, state)
15
15
 
16
- fiber.timeout(duration) do
16
+ fiber.with_timeout(duration) do
17
17
  result = Fiber.yield
18
18
  raise result if result.is_a? Exception
19
19
  end
@@ -80,12 +80,12 @@ module Async
80
80
  @subjects[subject.class] = false
81
81
  end
82
82
 
83
- def log(level, *args, &block)
83
+ def log(level, *arguments, &block)
84
84
  unless level.is_a? Symbol
85
85
  level = LEVELS[level]
86
86
  end
87
87
 
88
- self.send(level, *args, &block)
88
+ self.send(level, *arguments, &block)
89
89
  end
90
90
 
91
91
  def format(subject = nil, *arguments, &block)
@@ -204,7 +204,6 @@ module Async
204
204
  @children.each(&:stop)
205
205
 
206
206
  # TODO Should we also clear all timers?
207
-
208
207
  @selector.close
209
208
  @selector = nil
210
209
  end
@@ -231,18 +230,15 @@ module Async
231
230
  timer.cancel if timer
232
231
  end
233
232
 
234
- # Invoke the block, but after the timeout, raise {TimeoutError} in any
235
- # currenly blocking operation.
233
+ # Invoke the block, but after the specified timeout, raise {TimeoutError} in any currenly blocking operation. If the block runs to completion before the timeout occurs or there are no non-blocking operations after the timeout expires, the code will complete without any exception.
236
234
  # @param duration [Numeric] The time in seconds, in which the task should
237
235
  # complete.
238
- def timeout(duration, exception = TimeoutError)
239
- backtrace = caller
236
+ def with_timeout(timeout, exception = TimeoutError)
240
237
  fiber = Fiber.current
241
238
 
242
- timer = self.after(duration) do
239
+ timer = self.after(timeout) do
243
240
  if fiber.alive?
244
241
  error = exception.new("execution expired")
245
- error.set_backtrace backtrace
246
242
  fiber.resume error
247
243
  end
248
244
  end
@@ -251,5 +247,12 @@ module Async
251
247
  ensure
252
248
  timer.cancel if timer
253
249
  end
250
+
251
+ # TODO remove
252
+ def timeout(*args, &block)
253
+ warn "#{self.class}\#timeout(...) is deprecated, use #{self.class}\#with_timeout(...) instead."
254
+
255
+ with_timeout(*args, &block)
256
+ end
254
257
  end
255
258
  end
@@ -76,7 +76,7 @@ module Async
76
76
 
77
77
  # @attr ios [Reactor] The reactor the task was created within.
78
78
  attr :reactor
79
- def_delegators :@reactor, :timeout, :sleep
79
+ def_delegators :@reactor, :with_timeout, :timeout, :sleep
80
80
 
81
81
  # Yield back to the reactor and allow other fibers to execute.
82
82
  def yield
@@ -90,7 +90,7 @@ module Async
90
90
  # @attr status [Symbol] The status of the execution of the fiber, one of `:initialized`, `:running`, `:complete`, `:stopped` or `:failed`.
91
91
  attr :status
92
92
 
93
- # Resume the execution of the task.
93
+ # Begin the execution of the task.
94
94
  def run(*args)
95
95
  if @status == :initialized
96
96
  @status = :running
@@ -124,6 +124,7 @@ module Async
124
124
 
125
125
  # Deprecated.
126
126
  alias result wait
127
+ # Soon to become attr :result
127
128
 
128
129
  # Stop the task and all of its children.
129
130
  # @return [void]
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Async
22
- VERSION = "1.14.0"
22
+ VERSION = "1.15.0"
23
23
  end
@@ -92,14 +92,14 @@ module Async
92
92
  end
93
93
 
94
94
  # Wait for the io to become readable.
95
- def wait_readable(duration = nil)
95
+ def wait_readable(timeout = nil)
96
96
  raise WaitError if @readable
97
97
 
98
98
  self.reactor = Task.current.reactor
99
99
 
100
100
  begin
101
101
  @readable = Fiber.current
102
- wait_for(duration)
102
+ wait_for(timeout)
103
103
  ensure
104
104
  @readable = nil
105
105
  @monitor.interests = interests if @monitor
@@ -107,14 +107,14 @@ module Async
107
107
  end
108
108
 
109
109
  # Wait for the io to become writable.
110
- def wait_writable(duration = nil)
110
+ def wait_writable(timeout = nil)
111
111
  raise WaitError if @writable
112
112
 
113
113
  self.reactor = Task.current.reactor
114
114
 
115
115
  begin
116
116
  @writable = Fiber.current
117
- wait_for(duration)
117
+ wait_for(timeout)
118
118
  ensure
119
119
  @writable = nil
120
120
  @monitor.interests = interests if @monitor
@@ -123,14 +123,14 @@ module Async
123
123
 
124
124
  # Wait fo the io to become either readable or writable.
125
125
  # @param duration [Float] timeout after the given duration if not `nil`.
126
- def wait_any(duration = nil)
126
+ def wait_any(timeout = nil)
127
127
  raise WaitError if @any
128
128
 
129
129
  self.reactor = Task.current.reactor
130
130
 
131
131
  begin
132
132
  @any = Fiber.current
133
- wait_for(duration)
133
+ wait_for(timeout)
134
134
  ensure
135
135
  @any = nil
136
136
  @monitor.interests = interests if @monitor
@@ -195,7 +195,7 @@ module Async
195
195
  end
196
196
  end
197
197
 
198
- def wait_for(duration)
198
+ def wait_for(timeout)
199
199
  if @monitor
200
200
  @monitor.interests = interests
201
201
  else
@@ -203,8 +203,8 @@ module Async
203
203
  end
204
204
 
205
205
  # If the user requested an explicit timeout for this operation:
206
- if duration
207
- @reactor.timeout(duration) do
206
+ if timeout
207
+ @reactor.with_timeout(timeout) do
208
208
  Task.yield
209
209
  end
210
210
  else
@@ -18,6 +18,8 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
+ require 'benchmark/ips'
22
+
21
23
  RSpec.describe Async::Reactor do
22
24
  describe '#run' do
23
25
  it "can run tasks on different fibers" do
@@ -118,7 +120,7 @@ RSpec.describe Async::Reactor do
118
120
  end
119
121
  end
120
122
 
121
- describe '#timeout' do
123
+ describe '#with_timeout' do
122
124
  let(:duration) {1}
123
125
 
124
126
  it "stops immediately" do
@@ -127,7 +129,7 @@ RSpec.describe Async::Reactor do
127
129
  described_class.run do |task|
128
130
  condition = Async::Condition.new
129
131
 
130
- task.timeout(duration) do
132
+ task.with_timeout(duration) do
131
133
  task.async do
132
134
  condition.wait
133
135
  end
@@ -150,12 +152,29 @@ RSpec.describe Async::Reactor do
150
152
  it "raises specified exception" do
151
153
  expect do
152
154
  described_class.run do |task|
153
- task.timeout(0.0, timeout_class) do
155
+ task.with_timeout(0.0, timeout_class) do
154
156
  task.sleep(1.0)
155
157
  end
156
158
  end.wait
157
159
  end.to raise_exception(timeout_class)
158
160
  end
161
+
162
+ it "should be fast to use timeouts" do
163
+ Benchmark.ips do |x|
164
+ x.report('Reactor#with_timeout') do |repeats|
165
+ Async do |task|
166
+ reactor = task.reactor
167
+
168
+ repeats.times do
169
+ reactor.with_timeout(1) do
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ x.compare!
176
+ end
177
+ end
159
178
  end
160
179
 
161
180
  describe '#to_s' do
@@ -199,10 +199,10 @@ RSpec.describe Async::Task do
199
199
  end
200
200
  end
201
201
 
202
- describe '#timeout' do
202
+ describe '#with_timeout' do
203
203
  it "can extend timeout" do
204
204
  reactor.async do |task|
205
- task.timeout(0.2) do |timer|
205
+ task.with_timeout(0.2) do |timer|
206
206
  task.sleep(0.1)
207
207
 
208
208
  expect(timer.fires_in).to be_within(10).percent_of(0.1)
@@ -221,7 +221,7 @@ RSpec.describe Async::Task do
221
221
 
222
222
  reactor.async do |task|
223
223
  begin
224
- task.timeout(0.01) do
224
+ task.with_timeout(0.01) do
225
225
  state = :started
226
226
  task.sleep(10)
227
227
  state = :finished
@@ -241,7 +241,7 @@ RSpec.describe Async::Task do
241
241
 
242
242
  reactor.async do |task|
243
243
  state = :started
244
- task.timeout(0.01) do
244
+ task.with_timeout(0.01) do
245
245
  task.sleep(0.001)
246
246
  state = :finished
247
247
  end
@@ -251,6 +251,26 @@ RSpec.describe Async::Task do
251
251
 
252
252
  expect(state).to be == :finished
253
253
  end
254
+
255
+ def sleep_forever
256
+ while true
257
+ Async::Task.current.sleep(1)
258
+ end
259
+ end
260
+
261
+ it "contains useful backtrace" do
262
+ task = Async do |task|
263
+ task.with_timeout(1.0) do
264
+ sleep_forever
265
+ end
266
+ end
267
+
268
+ expect{task.wait}.to raise_error(Async::TimeoutError)
269
+
270
+ # TODO replace this with task.result
271
+ task.wait rescue error = $!
272
+ expect(error.backtrace).to include(/sleep_forever/)
273
+ end
254
274
  end
255
275
 
256
276
  describe '#wait' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-17 00:00:00.000000000 Z
11
+ date: 2019-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r