async 1.25.0 → 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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/async/barrier.rb +1 -1
  3. data/lib/async/node.rb +171 -49
  4. data/lib/async/queue.rb +5 -1
  5. data/lib/async/reactor.rb +16 -11
  6. data/lib/async/version.rb +1 -1
  7. metadata +54 -99
  8. data/.editorconfig +0 -6
  9. data/.github/workflows/development.yml +0 -55
  10. data/.gitignore +0 -14
  11. data/.rspec +0 -3
  12. data/.yardopts +0 -1
  13. data/Gemfile +0 -20
  14. data/Guardfile +0 -14
  15. data/README.md +0 -385
  16. data/Rakefile +0 -40
  17. data/async.gemspec +0 -34
  18. data/bake.rb +0 -33
  19. data/benchmark/async_vs_lightio.rb +0 -84
  20. data/benchmark/fiber_count.rb +0 -10
  21. data/benchmark/rubies/README.md +0 -51
  22. data/benchmark/rubies/benchmark.rb +0 -220
  23. data/benchmark/thread_count.rb +0 -9
  24. data/benchmark/thread_vs_fiber.rb +0 -45
  25. data/examples/async_method.rb +0 -60
  26. data/examples/callback/loop.rb +0 -44
  27. data/examples/capture/README.md +0 -59
  28. data/examples/capture/capture.rb +0 -116
  29. data/examples/fibers.rb +0 -178
  30. data/examples/queue/producer.rb +0 -28
  31. data/examples/sleep_sort.rb +0 -40
  32. data/examples/stop/condition.rb +0 -31
  33. data/examples/stop/sleep.rb +0 -42
  34. data/gems/event.gemfile +0 -4
  35. data/logo.png +0 -0
  36. data/logo.svg +0 -64
  37. data/papers/1982 Grossman.pdf +0 -0
  38. data/papers/1987 ODell.pdf +0 -0
  39. data/spec/async/barrier_spec.rb +0 -116
  40. data/spec/async/chainable_async_examples.rb +0 -13
  41. data/spec/async/clock_spec.rb +0 -37
  42. data/spec/async/condition_examples.rb +0 -105
  43. data/spec/async/condition_spec.rb +0 -72
  44. data/spec/async/logger_spec.rb +0 -65
  45. data/spec/async/node_spec.rb +0 -175
  46. data/spec/async/notification_spec.rb +0 -66
  47. data/spec/async/performance_spec.rb +0 -72
  48. data/spec/async/queue_spec.rb +0 -129
  49. data/spec/async/reactor/nested_spec.rb +0 -52
  50. data/spec/async/reactor_spec.rb +0 -233
  51. data/spec/async/semaphore_spec.rb +0 -169
  52. data/spec/async/task_spec.rb +0 -466
  53. data/spec/async/wrapper_spec.rb +0 -203
  54. data/spec/async_spec.rb +0 -33
  55. data/spec/enumerator_spec.rb +0 -83
  56. data/spec/kernel/async_spec.rb +0 -33
  57. data/spec/kernel/sync_spec.rb +0 -54
  58. data/spec/spec_helper.rb +0 -18
@@ -1,72 +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
- require 'async/condition'
25
-
26
- require_relative 'condition_examples'
27
-
28
- RSpec.describe Async::Condition do
29
- include_context Async::RSpec::Reactor
30
-
31
- it 'should continue after condition is signalled' do
32
- task = reactor.async do
33
- subject.wait
34
- end
35
-
36
- expect(task.status).to be :running
37
-
38
- # This will cause the task to exit:
39
- subject.signal
40
-
41
- expect(task.status).to be :complete
42
-
43
- task.stop
44
- end
45
-
46
- it 'can stop nested task' do
47
- producer = nil
48
-
49
- consumer = reactor.async do |task|
50
- condition = Async::Condition.new
51
-
52
- producer = task.async do |subtask|
53
- subtask.yield
54
- condition.signal
55
- subtask.sleep(10)
56
- end
57
-
58
- condition.wait
59
- expect do
60
- producer.stop
61
- end.to_not raise_error
62
- end
63
-
64
- consumer.wait
65
- producer.wait
66
-
67
- expect(producer.status).to be :stopped
68
- expect(consumer.status).to be :complete
69
- end
70
-
71
- it_behaves_like Async::Condition
72
- end
@@ -1,65 +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/logger'
25
- require 'console/capture'
26
-
27
- RSpec.describe 'Async.logger' do
28
- let(:name) {"nested"}
29
- let(:message) {"Talk is cheap. Show me the code."}
30
-
31
- let(:capture) {Console::Capture.new}
32
- let(:logger) {Console::Logger.new(capture, name: name)}
33
-
34
- it "can use nested logger" do
35
- Async(logger: logger) do |task|
36
- expect(task.logger).to be == logger
37
- logger.warn message
38
- end.wait
39
-
40
- expect(capture.events.last).to include({
41
- severity: :warn,
42
- name: name,
43
- subject: message,
44
- })
45
- end
46
-
47
- it "can change nested logger" do
48
- Async do |parent|
49
- parent.async(logger: logger) do |task|
50
- expect(task.logger).to be == logger
51
- expect(Async.logger).to be == logger
52
- end.wait
53
- end.wait
54
- end
55
-
56
- it "can use parent logger" do
57
- Async(logger: logger) do |parent|
58
- child = parent.async{|task| task.yield}
59
-
60
- expect(parent.logger).to be == logger
61
- expect(child.logger).to be == logger
62
- expect(Async.logger).to be == logger
63
- end.wait
64
- end
65
- end
@@ -1,175 +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/node'
24
-
25
- RSpec.describe Async::Node do
26
- describe '#parent=' do
27
- let(:child) {Async::Node.new(subject)}
28
-
29
- it "should construct nested tree" do
30
- expect(child.parent).to be subject
31
- expect(subject.children).to include(child)
32
- end
33
-
34
- it "should break nested tree" do
35
- child.parent = nil
36
-
37
- expect(child.parent).to be_nil
38
- expect(subject.children).to be_empty
39
- end
40
-
41
- it "can consume bottom to top" do
42
- child.consume
43
-
44
- expect(child.parent).to be_nil
45
- expect(subject.children).to be_empty
46
- end
47
- end
48
-
49
- describe '#print_hierarchy' do
50
- let(:buffer) {StringIO.new}
51
- let(:output) {buffer.string}
52
- let(:lines) {output.lines}
53
-
54
- let!(:child) {Async::Node.new(subject)}
55
-
56
- it "can print hierarchy to bufffer" do
57
- subject.print_hierarchy(buffer)
58
-
59
- expect(lines.size).to be 2
60
-
61
- expect(lines[0]).to be =~ /#<Async::Node:0x\h+>\n/
62
- expect(lines[1]).to be =~ /\t#<Async::Node:0x\h+>\n/
63
- end
64
- end
65
-
66
- describe '#consume' do
67
- let(:middle) {Async::Node.new(subject)}
68
- let(:bottom) {Async::Node.new(middle)}
69
-
70
- it "can't consume middle node" do
71
- expect(bottom.parent).to be middle
72
-
73
- middle.consume
74
-
75
- expect(bottom.parent).to be middle
76
- end
77
- end
78
-
79
- describe '#annotate' do
80
- let(:annotation) {'reticulating splines'}
81
-
82
- it "should have no annotation by default" do
83
- expect(subject.annotation).to be_nil
84
- end
85
-
86
- it 'should output annotation when invoking #to_s' do
87
- subject.annotate(annotation) do
88
- expect(subject.to_s).to include(annotation)
89
- end
90
- end
91
-
92
- it 'can assign annotation' do
93
- subject.annotate(annotation)
94
-
95
- expect(subject.annotation).to be == annotation
96
- end
97
- end
98
-
99
- describe '#transient' do
100
- it 'can move transient child to parent' do
101
- # This example represents a persistent web connection (middle) with a background reader (child). We look at how when that connection goes out of scope, what happens to the child.
102
-
103
- # subject -> middle -> child (transient)
104
-
105
- middle = Async::Node.new(subject)
106
- child = Async::Node.new(middle, transient: true)
107
-
108
- expect(child).to be_transient
109
- expect(middle).to be_finished
110
-
111
- allow(child).to receive(:finished?).and_return(false)
112
-
113
- middle.consume
114
-
115
- # subject -> child (transient)
116
- expect(child.parent).to be subject
117
- expect(subject.children).to include(child)
118
- expect(subject.children).to_not include(middle)
119
-
120
- expect(child).to_not be_finished
121
- expect(subject).to be_finished
122
-
123
- expect(child).to receive(:stop)
124
- subject.stop
125
- end
126
-
127
- it 'can move transient sibling to parent' do
128
- # This example represents a server task (middle) which has a single task listening on incoming connections (child2), and a transient task which is monitoring those connections/some shared resource (child1). We look at what happens when the server listener finishes.
129
-
130
- # subject -> middle -> child1 (transient)
131
- # -> child2
132
- middle = Async::Node.new(subject)
133
- child1 = Async::Node.new(middle, transient: true)
134
- child2 = Async::Node.new(middle)
135
-
136
- allow(child1).to receive(:finished?).and_return(false)
137
-
138
- middle.consume
139
-
140
- # subject -> middle -> child1 (transient)
141
- # -> child2
142
- expect(child1.parent).to be middle
143
- expect(child2.parent).to be middle
144
- expect(middle.parent).to be subject
145
- expect(subject.children).to include(middle)
146
- expect(middle.children).to include(child1)
147
- expect(middle.children).to include(child2)
148
-
149
- child2.consume
150
-
151
- # subject -> child1 (transient)
152
- expect(child1.parent).to be subject
153
- expect(child2.parent).to be_nil
154
- expect(middle.parent).to be_nil
155
- expect(subject.children).to include(child1)
156
- expect(middle.children).to be_nil
157
- end
158
-
159
- it 'ignores non-transient children of transient parent' do
160
- # subject -> middle (transient) -> child
161
- middle = Async::Node.new(subject, transient: true)
162
- child = Async::Node.new(middle)
163
-
164
- allow(middle).to receive(:finished?).and_return(false)
165
-
166
- child.consume
167
-
168
- # subject -> middle (transient)
169
- expect(child.parent).to be_nil
170
- expect(middle.parent).to be subject
171
- expect(subject.children).to include(middle)
172
- expect(middle.children).to be_empty
173
- end
174
- end
175
- end
@@ -1,66 +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
- require 'async/notification'
25
-
26
- require_relative 'condition_examples'
27
-
28
- RSpec.describe Async::Notification do
29
- include_context Async::RSpec::Reactor
30
-
31
- it 'should continue after notification is signalled' do
32
- sequence = []
33
-
34
- task = reactor.async do
35
- sequence << :waiting
36
- subject.wait
37
- sequence << :resumed
38
- end
39
-
40
- expect(task.status).to be :running
41
-
42
- sequence << :running
43
- # This will cause the task to exit:
44
- subject.signal
45
- sequence << :signalled
46
-
47
- expect(task.status).to be :running
48
-
49
- sequence << :yielding
50
- reactor.yield
51
- sequence << :finished
52
-
53
- expect(task.status).to be :complete
54
-
55
- expect(sequence).to be == [
56
- :waiting,
57
- :running,
58
- :signalled,
59
- :yielding,
60
- :resumed,
61
- :finished
62
- ]
63
- end
64
-
65
- it_behaves_like Async::Condition
66
- end
@@ -1,72 +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 'benchmark/ips'
24
- require 'async'
25
-
26
- RSpec.describe Async::Wrapper do
27
- let(:pipe) {IO.pipe}
28
-
29
- after do
30
- pipe.each(&:close)
31
- end
32
-
33
- let(:input) {described_class.new(pipe.first)}
34
- let(:output) {described_class.new(pipe.last)}
35
-
36
- it "should be fast to wait until readable" do
37
- Benchmark.ips do |x|
38
- x.report('Wrapper#wait_readable') do |repeats|
39
- Async do |task|
40
- input = Async::Wrapper.new(pipe.first, task.reactor)
41
- output = pipe.last
42
-
43
- repeats.times do
44
- output.write(".")
45
- input.wait_readable
46
- input.io.read(1)
47
- end
48
-
49
- input.reactor = nil
50
- end
51
- end
52
-
53
- x.report('Reactor#register') do |repeats|
54
- Async do |task|
55
- input = pipe.first
56
- monitor = task.reactor.register(input, :r)
57
- output = pipe.last
58
-
59
- repeats.times do
60
- output.write(".")
61
- Async::Task.yield
62
- input.read(1)
63
- end
64
-
65
- monitor.close
66
- end
67
- end
68
-
69
- x.compare!
70
- end
71
- end
72
- end