async 1.25.2 → 1.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/async/barrier.rb +1 -1
  3. data/lib/async/clock.rb +33 -1
  4. data/lib/async/logger.rb +1 -6
  5. data/lib/async/node.rb +20 -2
  6. data/lib/async/queue.rb +5 -1
  7. data/lib/async/reactor.rb +73 -12
  8. data/lib/async/scheduler.rb +112 -0
  9. data/lib/async/task.rb +11 -3
  10. data/lib/async/version.rb +1 -1
  11. metadata +46 -104
  12. data/.editorconfig +0 -6
  13. data/.github/workflows/development.yml +0 -55
  14. data/.gitignore +0 -14
  15. data/.rspec +0 -3
  16. data/.yardopts +0 -1
  17. data/Gemfile +0 -20
  18. data/Guardfile +0 -14
  19. data/README.md +0 -385
  20. data/Rakefile +0 -40
  21. data/async.gemspec +0 -34
  22. data/bake.rb +0 -33
  23. data/benchmark/async_vs_lightio.rb +0 -84
  24. data/benchmark/fiber_count.rb +0 -10
  25. data/benchmark/rubies/README.md +0 -51
  26. data/benchmark/rubies/benchmark.rb +0 -220
  27. data/benchmark/thread_count.rb +0 -9
  28. data/benchmark/thread_vs_fiber.rb +0 -45
  29. data/examples/async_method.rb +0 -60
  30. data/examples/callback/loop.rb +0 -44
  31. data/examples/capture/README.md +0 -59
  32. data/examples/capture/capture.rb +0 -116
  33. data/examples/fibers.rb +0 -178
  34. data/examples/queue/producer.rb +0 -28
  35. data/examples/sleep_sort.rb +0 -40
  36. data/examples/stop/condition.rb +0 -31
  37. data/examples/stop/sleep.rb +0 -42
  38. data/gems/event.gemfile +0 -4
  39. data/logo.png +0 -0
  40. data/logo.svg +0 -64
  41. data/papers/1982 Grossman.pdf +0 -0
  42. data/papers/1987 ODell.pdf +0 -0
  43. data/spec/async/barrier_spec.rb +0 -116
  44. data/spec/async/chainable_async_examples.rb +0 -13
  45. data/spec/async/clock_spec.rb +0 -37
  46. data/spec/async/condition_examples.rb +0 -105
  47. data/spec/async/condition_spec.rb +0 -72
  48. data/spec/async/logger_spec.rb +0 -65
  49. data/spec/async/node_spec.rb +0 -193
  50. data/spec/async/notification_spec.rb +0 -66
  51. data/spec/async/performance_spec.rb +0 -72
  52. data/spec/async/queue_spec.rb +0 -129
  53. data/spec/async/reactor/nested_spec.rb +0 -52
  54. data/spec/async/reactor_spec.rb +0 -253
  55. data/spec/async/semaphore_spec.rb +0 -169
  56. data/spec/async/task_spec.rb +0 -476
  57. data/spec/async/wrapper_spec.rb +0 -203
  58. data/spec/async_spec.rb +0 -33
  59. data/spec/enumerator_spec.rb +0 -83
  60. data/spec/kernel/async_spec.rb +0 -33
  61. data/spec/kernel/sync_spec.rb +0 -54
  62. data/spec/spec_helper.rb +0 -18
@@ -1,203 +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/rspec"
24
-
25
- RSpec.describe Async::Wrapper do
26
- include_context Async::RSpec::Reactor
27
-
28
- let(:pipe) {IO.pipe}
29
- let(:input) {Async::Wrapper.new(pipe.last)}
30
- let(:output) {Async::Wrapper.new(pipe.first)}
31
-
32
- after(:each) do
33
- input.close unless input.closed?
34
- output.close unless output.closed?
35
-
36
- expect(input.monitor).to be_nil
37
- expect(output.monitor).to be_nil
38
- end
39
-
40
- describe '#wait_readable' do
41
- it "can wait to be readable" do
42
- reader = reactor.async do
43
- expect(output.wait_readable).to be_truthy
44
- end
45
-
46
- input.io.write('Hello World')
47
- reader.wait
48
- end
49
-
50
- it "can timeout if no event occurs" do
51
- expect do
52
- output.wait_readable(0.1)
53
- end.to raise_exception(Async::TimeoutError)
54
- end
55
-
56
- it "can wait for readability in sequential tasks" do
57
- reactor.async do
58
- input.wait_writable(1)
59
- input.io.write('Hello World')
60
- end
61
-
62
- 2.times do
63
- reactor.async do
64
- expect(output.wait_readable(1)).to be_truthy
65
- end.wait
66
- end
67
- end
68
-
69
- it "can be cancelled" do
70
- reactor.async do
71
- expect do
72
- output.wait_readable
73
- end.to raise_exception(Async::Wrapper::Cancelled)
74
- end
75
-
76
- expect(output.monitor).to_not be_nil
77
- end
78
- end
79
-
80
- describe '#wait_writable' do
81
- it "can wait to be writable" do
82
- expect(input.wait_writable).to be_truthy
83
- end
84
-
85
- it "can be cancelled while waiting to be readable" do
86
- reactor.async do
87
- expect do
88
- input.wait_readable
89
- end.to raise_exception(Async::Wrapper::Cancelled)
90
- end
91
-
92
- # This reproduces the race condition that can occur if two tasks are resumed in sequence.
93
-
94
- # Resume task 1 which closes IO:
95
- output.close
96
-
97
- # Resume task 2:
98
- expect do
99
- output.resume
100
- end.to_not raise_exception
101
- end
102
-
103
- it "can be cancelled" do
104
- reactor.async do
105
- expect do
106
- input.wait_readable
107
- end.to raise_exception(Async::Wrapper::Cancelled)
108
- end
109
-
110
- expect(input.monitor).to_not be_nil
111
- end
112
- end
113
-
114
- describe "#wait_any" do
115
- it "can wait for any events" do
116
- reactor.async do
117
- input.wait_any(1)
118
- input.io.write('Hello World')
119
- end
120
-
121
- expect(output.wait_readable(1)).to be_truthy
122
- end
123
-
124
- it "can wait for readability in one task and writability in another" do
125
- reactor.async do
126
- expect do
127
- input.wait_readable(1)
128
- end.to raise_exception(Async::Wrapper::Cancelled)
129
- end
130
-
131
- expect(input.monitor.interests).to be == :r
132
-
133
- reactor.async do
134
- input.wait_writable
135
-
136
- input.close
137
- output.close
138
- end.wait
139
- end
140
-
141
- it "fails if waiting on from multiple tasks" do
142
- input.reactor = reactor
143
-
144
- reactor.async do
145
- expect do
146
- input.wait_readable
147
- end.to raise_exception(Async::Wrapper::Cancelled)
148
- end
149
-
150
- expect(input.monitor.interests).to be == :r
151
-
152
- reactor.async do
153
- expect do
154
- input.wait_readable
155
- end.to raise_exception(Async::Wrapper::WaitError)
156
- end
157
- end
158
- end
159
-
160
- describe '#reactor=' do
161
- it 'can assign a wrapper to a reactor' do
162
- input.reactor = reactor
163
-
164
- expect(input.reactor).to be == reactor
165
- end
166
-
167
- it 'assigns current reactor when waiting for events' do
168
- input.wait_writable
169
-
170
- expect(input.reactor).to be == reactor
171
- end
172
- end
173
-
174
- describe '#dup' do
175
- let(:dup) {input.dup}
176
-
177
- it 'dups the underlying io' do
178
- expect(dup.io).to_not eq input.io
179
-
180
- dup.close
181
-
182
- expect(input).to_not be_closed
183
- end
184
- end
185
-
186
- describe '#close' do
187
- it "closes monitor when closing wrapper" do
188
- input.wait_writable
189
- expect(input.monitor).to_not be_nil
190
- input.close
191
- expect(input.monitor).to be_nil
192
- end
193
-
194
- it "can't wait on closed wrapper" do
195
- input.close
196
- output.close
197
-
198
- expect do
199
- output.wait_readable
200
- end.to raise_exception(IOError, /closed stream/)
201
- end
202
- end
203
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, 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
-
25
- RSpec.describe Async do
26
- describe '.run' do
27
- it "can run an asynchronous task" do
28
- Async.run do |task|
29
- expect(task).to be_a Async::Task
30
- end
31
- end
32
- end
33
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- # Copyright, 2018, by Sokolov Yura aka funny-falcon
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
-
24
- RSpec.describe Enumerator do
25
- def some_yielder(task)
26
- yield 1
27
- task.sleep(0.002)
28
- yield 2
29
- end
30
-
31
- def enum(task)
32
- to_enum(:some_yielder, task)
33
- end
34
-
35
- it "should play well with Enumerator as internal iterator" do
36
- # no fiber really used in internal iterator,
37
- # but let this test be here for completness
38
- ar = nil
39
- Async do |task|
40
- ar = enum(task).to_a
41
- end
42
- expect(ar).to be == [1, 2]
43
- end
44
-
45
- it "should play well with Enumerator as external iterator", pending: "expected failure" do
46
- ar = []
47
- Async do |task|
48
- en = enum(task)
49
- ar << en.next
50
- ar << en.next
51
- ar << begin en.next rescue $! end
52
- end
53
- expect(ar[0]).to be == 1
54
- expect(ar[1]).to be == 2
55
- expect(ar[2]).to be_a StopIteration
56
- end
57
-
58
- it "should play well with Enumerator.zip(Enumerator) method", pending: "expected failure" do
59
- Async do |task|
60
- ar = [:a, :b, :c, :d].each.zip(enum(task))
61
- expect(ar).to be == [[:a, 1], [:b, 2], [:c, nil], [:d, nil]]
62
- end.wait
63
- end
64
-
65
- it "should play with explicit Fiber usage", pending: "expected failure" do
66
- ar = []
67
- Async do |task|
68
- fib = Fiber.new {
69
- Fiber.yield 1
70
- task.sleep(0.002)
71
- Fiber.yield 2
72
- }
73
- ar << fib.resume
74
- ar << fib.resume
75
- ar << fib.resume
76
- ar << begin en.next rescue $! end
77
- end
78
- expect(ar[0]).to be == 1
79
- expect(ar[1]).to be == 2
80
- expect(ar[2]).to be nil
81
- expect(ar[3]).to be_a FiberError
82
- end
83
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, 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 'kernel/async'
24
-
25
- RSpec.describe Async do
26
- describe '#Async' do
27
- it "can run an asynchronous task" do
28
- Async do |task|
29
- expect(task).to be_a Async::Task
30
- end
31
- end
32
- end
33
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, 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 'kernel/async'
24
- require 'kernel/sync'
25
-
26
- RSpec.describe Kernel do
27
- describe '#Sync' do
28
- let(:value) {10}
29
-
30
- it "can run a synchronous task" do
31
- result = Sync do |task|
32
- expect(Async::Task.current).to_not be nil
33
- expect(Async::Task.current).to be task
34
-
35
- next value
36
- end
37
-
38
- expect(result).to be == value
39
- end
40
-
41
- it "can run inside reactor" do
42
- Async do |task|
43
- result = Sync do |sync_task|
44
- expect(Async::Task.current).to be task
45
- expect(sync_task).to be task
46
-
47
- next value
48
- end
49
-
50
- expect(result).to be == value
51
- end
52
- end
53
- end
54
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "covered/rspec"
4
-
5
- if RUBY_PLATFORM =~ /darwin/
6
- Q = 20
7
- else
8
- Q = 1
9
- end
10
-
11
- RSpec.configure do |config|
12
- # Enable flags like --only-failures and --next-failure
13
- config.example_status_persistence_file_path = ".rspec_status"
14
-
15
- config.expect_with :rspec do |c|
16
- c.syntax = :expect
17
- end
18
- end