async 1.26.1 → 1.26.2

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/async/barrier.rb +1 -1
  3. data/lib/async/version.rb +1 -1
  4. metadata +54 -99
  5. data/.editorconfig +0 -6
  6. data/.github/workflows/development.yml +0 -55
  7. data/.gitignore +0 -14
  8. data/.rspec +0 -3
  9. data/.yardopts +0 -1
  10. data/Gemfile +0 -20
  11. data/Guardfile +0 -14
  12. data/README.md +0 -385
  13. data/Rakefile +0 -40
  14. data/async.gemspec +0 -34
  15. data/bake.rb +0 -33
  16. data/benchmark/async_vs_lightio.rb +0 -84
  17. data/benchmark/fiber_count.rb +0 -10
  18. data/benchmark/rubies/README.md +0 -51
  19. data/benchmark/rubies/benchmark.rb +0 -220
  20. data/benchmark/thread_count.rb +0 -9
  21. data/benchmark/thread_vs_fiber.rb +0 -45
  22. data/examples/async_method.rb +0 -60
  23. data/examples/callback/loop.rb +0 -44
  24. data/examples/capture/README.md +0 -59
  25. data/examples/capture/capture.rb +0 -116
  26. data/examples/fibers.rb +0 -178
  27. data/examples/queue/producer.rb +0 -28
  28. data/examples/sleep_sort.rb +0 -40
  29. data/examples/stop/condition.rb +0 -31
  30. data/examples/stop/sleep.rb +0 -42
  31. data/gems/event.gemfile +0 -4
  32. data/logo.png +0 -0
  33. data/logo.svg +0 -64
  34. data/papers/1982 Grossman.pdf +0 -0
  35. data/papers/1987 ODell.pdf +0 -0
  36. data/spec/async/barrier_spec.rb +0 -116
  37. data/spec/async/chainable_async_examples.rb +0 -13
  38. data/spec/async/clock_spec.rb +0 -37
  39. data/spec/async/condition_examples.rb +0 -105
  40. data/spec/async/condition_spec.rb +0 -72
  41. data/spec/async/logger_spec.rb +0 -65
  42. data/spec/async/node_spec.rb +0 -193
  43. data/spec/async/notification_spec.rb +0 -66
  44. data/spec/async/performance_spec.rb +0 -72
  45. data/spec/async/queue_spec.rb +0 -133
  46. data/spec/async/reactor/nested_spec.rb +0 -52
  47. data/spec/async/reactor_spec.rb +0 -253
  48. data/spec/async/semaphore_spec.rb +0 -169
  49. data/spec/async/task_spec.rb +0 -476
  50. data/spec/async/wrapper_spec.rb +0 -203
  51. data/spec/async_spec.rb +0 -33
  52. data/spec/enumerator_spec.rb +0 -83
  53. data/spec/kernel/async_spec.rb +0 -39
  54. data/spec/kernel/sync_spec.rb +0 -54
  55. data/spec/spec_helper.rb +0 -18
@@ -1,476 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'async'
24
- require 'async/clock'
25
-
26
- RSpec.describe Async::Task do
27
- let(:reactor) {Async::Reactor.new}
28
-
29
- describe '#run' do
30
- it "can't be invoked twice" do
31
- task = reactor.async do |task|
32
- end
33
-
34
- expect{task.run}.to raise_exception(RuntimeError, /already running/)
35
- end
36
- end
37
-
38
- describe '#current?' do
39
- it "can check if it is the currently running task" do
40
- task = reactor.async do |task|
41
- expect(task).to be_current
42
- task.sleep(0.1)
43
- end
44
-
45
- expect(task).to_not be_current
46
- end
47
- end
48
-
49
- describe '#async' do
50
- it "can start child async tasks" do
51
- child = nil
52
-
53
- parent = reactor.async do |task|
54
- child = task.async do
55
- task.sleep(1)
56
- end
57
- end
58
-
59
- expect(parent).to_not be_nil
60
- expect(child).to_not be_nil
61
- expect(child.parent).to_not be_nil
62
- end
63
-
64
- it "can pass in arguments" do
65
- reactor.async do |task|
66
- task.async(:arg) do |task, arg|
67
- expect(arg).to be == :arg
68
- end.wait
69
- end.wait
70
- end
71
-
72
- it "can set initial annotation" do
73
- reactor.async(annotation: "Hello World") do |task|
74
- expect(task.annotation).to be == "Hello World"
75
- end.wait
76
- end
77
-
78
- it "can raise exceptions" do
79
- expect do
80
- reactor.async do |task|
81
- raise "boom"
82
- end.wait
83
- end.to raise_exception RuntimeError, /boom/
84
- end
85
-
86
- it "can raise exception after asynchronous operation" do
87
- task = nil
88
-
89
- expect do
90
- task = reactor.async do |task|
91
- task.sleep 0.1
92
-
93
- raise "boom"
94
- end
95
- end.to_not raise_exception
96
-
97
- reactor.run do
98
- expect do
99
- task.wait
100
- end.to raise_exception RuntimeError, /boom/
101
- end
102
- end
103
-
104
- it "can consume exceptions" do
105
- task = nil
106
-
107
- expect do
108
- task = reactor.async do |task|
109
- raise "boom"
110
- end
111
- end.to_not raise_exception
112
-
113
- expect do
114
- task.wait
115
- end.to raise_exception RuntimeError, /boom/
116
- end
117
-
118
- it "won't consume non-StandardError exceptions" do
119
- expect do
120
- reactor.async do |task|
121
- raise SignalException.new(:TERM)
122
- end
123
- end.to raise_exception(SignalException, /TERM/)
124
- end
125
- end
126
-
127
- describe '#yield' do
128
- it "can yield back to reactor" do
129
- state = nil
130
-
131
- reactor.async do |task|
132
- state = :started
133
- task.yield
134
- state = :finished
135
- end
136
-
137
- reactor.run
138
-
139
- expect(state).to be == :finished
140
- end
141
- end
142
-
143
- describe '#stop' do
144
- it "can be stopped" do
145
- state = nil
146
-
147
- task = reactor.async do |task|
148
- state = :started
149
- task.sleep(10)
150
- state = :finished
151
- end
152
-
153
- task.stop
154
-
155
- expect(state).to be == :started
156
- expect(task).to be_stopped
157
- end
158
-
159
- it "can stop nested tasks with exception handling" do
160
- task = reactor.async do |task|
161
- child = task.async do |subtask|
162
- subtask.sleep(1)
163
- end
164
-
165
- begin
166
- child.wait
167
- ensure
168
- child.stop
169
- end
170
- end
171
-
172
- subtask = task.children.first
173
- task.stop
174
-
175
- expect(task.status).to be :stopped
176
- expect(subtask.status).to be :stopped
177
- end
178
-
179
- it "can stop current task" do
180
- state = nil
181
-
182
- task = reactor.async do |task|
183
- state = :started
184
- task.stop
185
- state = :finished
186
- end
187
-
188
- expect(state).to be == :started
189
- expect(task).to be_stopped
190
- end
191
-
192
- it "can stop current task using exception" do
193
- state = nil
194
-
195
- task = reactor.async do |task|
196
- state = :started
197
- raise Async::Stop, "I'm finished."
198
- state = :finished
199
- end
200
-
201
- expect(state).to be == :started
202
- expect(task).to be_stopped
203
- end
204
-
205
- it "should stop direct child" do
206
- parent_task = child_task = nil
207
-
208
- reactor.async do |task|
209
- parent_task = task
210
- reactor.async do |task|
211
- child_task = task
212
- task.sleep(10)
213
- end
214
- task.sleep(10)
215
- end
216
-
217
- expect(parent_task).to_not be_nil
218
- expect(child_task).to_not be_nil
219
-
220
- expect(parent_task.fiber).to be_alive
221
- expect(child_task.fiber).to be_alive
222
-
223
- parent_task.stop
224
-
225
- expect(parent_task).to_not be_alive
226
- expect(child_task).to_not be_alive
227
- end
228
-
229
- it "can stop nested parent" do
230
- parent_task = nil
231
- children_tasks = []
232
-
233
- reactor.async do |task|
234
- parent_task = task
235
-
236
- reactor.async do |task|
237
- children_tasks << task
238
- task.sleep(2)
239
- end
240
-
241
- reactor.async do |task|
242
- children_tasks << task
243
- task.sleep(1)
244
- parent_task.stop
245
- end
246
-
247
- reactor.async do |task|
248
- children_tasks << task
249
- task.sleep(2)
250
- end
251
- end
252
-
253
- reactor.run
254
-
255
- expect(parent_task).to_not be_alive
256
- end
257
-
258
- it "should not remove running task" do
259
- top_task = middle_task = bottom_task = nil
260
-
261
- top_task = reactor.async do |task|
262
- middle_task = reactor.async do |task|
263
- bottom_task = reactor.async do |task|
264
- task.sleep(10)
265
- end
266
- task.sleep(10)
267
- end
268
- task.sleep(10)
269
- end
270
-
271
- bottom_task.stop
272
- expect(top_task.children).to include(middle_task)
273
- end
274
-
275
- it "can stop resumed task" do
276
- items = [1, 2, 3]
277
-
278
- Async do
279
- condition = Async::Condition.new
280
-
281
- producer = Async do |subtask|
282
- while item = items.pop
283
- subtask.yield # (1) Fiber.yield, (3) Reactor -> producer.resume
284
- condition.signal(item) # (4) consumer.resume(value)
285
- end
286
- end
287
-
288
- value = condition.wait # (2) value = Fiber.yield
289
- expect(value).to be == 3
290
- producer.stop # (5) [producer is resumed already] producer.stop
291
- end
292
-
293
- expect(items).to be == [1]
294
- end
295
- end
296
-
297
- describe '#sleep' do
298
- let(:duration) {0.01}
299
-
300
- it "can sleep for the requested duration" do
301
- state = nil
302
-
303
- reactor.async do |task|
304
- task.sleep(duration)
305
- state = :finished
306
- end
307
-
308
- time = Async::Clock.measure do
309
- reactor.run
310
- end
311
-
312
- # This is too unstable on travis.
313
- # expect(time).to be_within(50).percent_of(duration)
314
- expect(time).to be >= duration
315
- expect(state).to be == :finished
316
- end
317
- end
318
-
319
- describe '#with_timeout' do
320
- it "can extend timeout" do
321
- reactor.async do |task|
322
- task.with_timeout(0.2) do |timer|
323
- task.sleep(0.1)
324
-
325
- expect(timer.fires_in).to be_within(10 * Q).percent_of(0.1)
326
-
327
- timer.reset
328
-
329
- expect(timer.fires_in).to be_within(10 * Q).percent_of(0.2)
330
- end
331
- end
332
-
333
- reactor.run
334
- end
335
-
336
- it "will timeout if execution takes too long" do
337
- state = nil
338
-
339
- reactor.async do |task|
340
- begin
341
- task.with_timeout(0.01) do
342
- state = :started
343
- task.sleep(10)
344
- state = :finished
345
- end
346
- rescue Async::TimeoutError
347
- state = :timeout
348
- end
349
- end
350
-
351
- reactor.run
352
-
353
- expect(state).to be == :timeout
354
- end
355
-
356
- it "won't timeout if execution completes in time" do
357
- state = nil
358
-
359
- reactor.async do |task|
360
- state = :started
361
- task.with_timeout(0.01) do
362
- task.sleep(0.001)
363
- state = :finished
364
- end
365
- end
366
-
367
- reactor.run
368
-
369
- expect(state).to be == :finished
370
- end
371
-
372
- def sleep_forever
373
- while true
374
- Async::Task.current.sleep(1)
375
- end
376
- end
377
-
378
- it "contains useful backtrace" do
379
- task = Async do |task|
380
- task.with_timeout(1.0) do
381
- sleep_forever
382
- end
383
- end
384
-
385
- expect{task.wait}.to raise_error(Async::TimeoutError)
386
-
387
- # TODO replace this with task.result
388
- task.wait rescue error = $!
389
- expect(error.backtrace).to include(/sleep_forever/)
390
- end
391
- end
392
-
393
- describe '#wait' do
394
- it "will wait on another task to complete" do
395
- apples_task = reactor.async do |task|
396
- task.sleep(0.1)
397
-
398
- :apples
399
- end
400
-
401
- oranges_task = reactor.async do |task|
402
- task.sleep(0.01)
403
-
404
- :oranges
405
- end
406
-
407
- fruit_salad = reactor.async do |task|
408
- [apples_task.wait, oranges_task.wait]
409
- end
410
-
411
- reactor.run
412
-
413
- expect(fruit_salad.wait).to be == [:apples, :oranges]
414
- end
415
-
416
- it "will raise exceptions when checking result" do
417
- error_task = nil
418
-
419
- error_task = reactor.async do |task|
420
- raise RuntimeError, "brain not provided"
421
- end
422
-
423
- expect do
424
- error_task.wait
425
- end.to raise_exception(RuntimeError, /brain/)
426
- end
427
-
428
- it "will propagate exceptions after async operation" do
429
- error_task = nil
430
-
431
- error_task = reactor.async do |task|
432
- task.sleep(0.1)
433
-
434
- raise "boom"
435
- end
436
-
437
- innocent_task = reactor.async do |task|
438
- expect{error_task.wait}.to raise_exception RuntimeError, /boom/
439
- end
440
-
441
- expect do
442
- reactor.run
443
- end.to_not raise_exception
444
-
445
- expect(error_task).to be_finished
446
- expect(innocent_task).to be_finished
447
- end
448
- end
449
-
450
- describe '#children' do
451
- it "enumerates children in same order they are created" do
452
- tasks = 10.times.map do |i|
453
- reactor.async(annotation: "Task #{i}") {|task| task.sleep(1)}
454
- end
455
-
456
- expect(reactor.children.each.to_a).to be == tasks
457
- end
458
- end
459
-
460
- describe '#to_s' do
461
- it "should show running" do
462
- apples_task = reactor.async do |task|
463
- task.sleep(0.1)
464
- end
465
-
466
- expect(apples_task.to_s).to include "running"
467
- end
468
-
469
- it "should show complete" do
470
- apples_task = reactor.async do |task|
471
- end
472
-
473
- expect(apples_task.to_s).to include "complete"
474
- end
475
- end
476
- end