async 0.13.0 → 0.14.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 +4 -4
- data/.rspec +0 -1
- data/.travis.yml +2 -0
- data/README.md +56 -38
- data/Rakefile +4 -0
- data/async.gemspec +4 -3
- data/lib/async/node.rb +47 -0
- data/lib/async/reactor.rb +27 -34
- data/lib/async/task.rb +35 -65
- data/lib/async/version.rb +1 -1
- data/lib/async/wrapper.rb +35 -19
- data/spec/async/condition_spec.rb +1 -1
- data/spec/async/node_spec.rb +37 -0
- data/spec/async/reactor/nested_spec.rb +1 -1
- data/spec/async/reactor_spec.rb +22 -1
- data/spec/async/task_spec.rb +53 -1
- data/{lib/async/udp_socket.rb → spec/async/wrapper_spec.rb} +25 -9
- data/spec/spec_helper.rb +2 -35
- metadata +14 -25
- data/examples/aio.rb +0 -42
- data/examples/echo.rb +0 -40
- data/lib/async/io.rb +0 -109
- data/lib/async/socket.rb +0 -109
- data/lib/async/tcp_socket.rb +0 -35
- data/lib/async/unix_socket.rb +0 -33
- data/spec/async/tcp_socket_spec.rb +0 -106
- data/spec/async/udp_socket_spec.rb +0 -71
- data/spec/async/unix_socket_spec.rb +0 -53
data/lib/async/version.rb
CHANGED
data/lib/async/wrapper.rb
CHANGED
@@ -22,58 +22,74 @@ module Async
|
|
22
22
|
# Represents an asynchronous IO within a reactor.
|
23
23
|
class Wrapper
|
24
24
|
# @param io the native object to wrap.
|
25
|
-
# @param
|
26
|
-
|
25
|
+
# @param reactor [Reactor] the reactor that is managing this wrapper, or not specified, it's looked up by way of {Task.current}.
|
26
|
+
# @param bound [Boolean] whether the underlying socket will be closed if the wrapper is closed.
|
27
|
+
def initialize(io, reactor = nil)
|
27
28
|
@io = io
|
28
|
-
|
29
|
+
|
30
|
+
@reactor = reactor || Task.current.reactor
|
29
31
|
@monitor = nil
|
30
32
|
end
|
31
33
|
|
32
34
|
# The underlying native `io`.
|
33
35
|
attr :io
|
34
36
|
|
35
|
-
# The
|
36
|
-
attr :
|
37
|
+
# The reactor this wrapper is associated with.
|
38
|
+
attr :reactor
|
37
39
|
|
38
40
|
# Wait for the io to become readable.
|
39
|
-
def wait_readable
|
40
|
-
wait_any(:r)
|
41
|
+
def wait_readable(duration = nil)
|
42
|
+
wait_any(:r, duration)
|
41
43
|
end
|
42
44
|
|
43
45
|
# Wait for the io to become writable.
|
44
|
-
def wait_writable
|
45
|
-
wait_any(:w)
|
46
|
+
def wait_writable(duration = nil)
|
47
|
+
wait_any(:w, duration)
|
46
48
|
end
|
47
49
|
|
48
50
|
# Wait fo the io to become either readable or writable.
|
49
51
|
# @param interests [:r | :w | :rw] what events to wait for.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
52
|
+
# @param duration [Float] timeout after the given duration if not `nil`.
|
53
|
+
def wait_any(interests = :rw, duration = nil)
|
54
|
+
monitor(interests, duration)
|
54
55
|
end
|
55
56
|
|
56
57
|
# Close the monitor.
|
57
58
|
def close
|
58
|
-
|
59
|
-
|
59
|
+
close_monitor
|
60
|
+
|
61
|
+
@io.close if @io
|
60
62
|
end
|
61
63
|
|
62
64
|
private
|
63
65
|
|
66
|
+
def close_monitor
|
67
|
+
if @monitor
|
68
|
+
@monitor.close
|
69
|
+
@monitor = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
64
73
|
# Monitor the io for the given events
|
65
|
-
|
66
|
-
def monitor(interests)
|
74
|
+
def monitor(interests, duration = nil)
|
67
75
|
unless @monitor
|
68
|
-
@monitor = @
|
76
|
+
@monitor = @reactor.register(@io, interests)
|
69
77
|
else
|
70
78
|
@monitor.interests = interests
|
71
79
|
end
|
72
80
|
|
73
81
|
@monitor.value = Fiber.current
|
74
82
|
|
75
|
-
|
83
|
+
# If the user requested an explicit timeout for this operation:
|
84
|
+
if duration
|
85
|
+
@reactor.timeout(duration) do
|
86
|
+
Task.yield
|
87
|
+
end
|
88
|
+
else
|
89
|
+
Task.yield
|
90
|
+
end
|
76
91
|
|
92
|
+
return true
|
77
93
|
ensure
|
78
94
|
@monitor.value = nil if @monitor
|
79
95
|
end
|
data/spec/async/node_spec.rb
CHANGED
@@ -44,6 +44,23 @@ RSpec.describe Async::Node do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
describe '#print_hierarchy' do
|
48
|
+
let(:buffer) {StringIO.new}
|
49
|
+
let(:output) {buffer.string}
|
50
|
+
let(:lines) {output.lines}
|
51
|
+
|
52
|
+
let!(:child) {Async::Node.new(subject)}
|
53
|
+
|
54
|
+
it "can print hierarchy to bufffer" do
|
55
|
+
subject.print_hierarchy(buffer)
|
56
|
+
|
57
|
+
expect(lines.count).to be 2
|
58
|
+
|
59
|
+
expect(lines[0]).to be =~ /#<Async::Node:0x\h+>\n/
|
60
|
+
expect(lines[1]).to be =~ /\t#<Async::Node:0x\h+>\n/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
47
64
|
describe '#consume' do
|
48
65
|
let(:middle) {Async::Node.new(subject)}
|
49
66
|
let(:bottom) {Async::Node.new(middle)}
|
@@ -56,4 +73,24 @@ RSpec.describe Async::Node do
|
|
56
73
|
expect(bottom.parent).to be middle
|
57
74
|
end
|
58
75
|
end
|
76
|
+
|
77
|
+
describe '#annotate' do
|
78
|
+
let(:annotation) {'reticulating splines'}
|
79
|
+
|
80
|
+
it "should have no annotation by default" do
|
81
|
+
expect(subject.annotation).to be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should output annotation when invoking #to_s' do
|
85
|
+
subject.annotate(annotation) do
|
86
|
+
expect(subject.to_s).to include(annotation)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'can assign annotation' do
|
91
|
+
subject.annotate(annotation)
|
92
|
+
|
93
|
+
expect(subject.annotation).to be == annotation
|
94
|
+
end
|
95
|
+
end
|
59
96
|
end
|
data/spec/async/reactor_spec.rb
CHANGED
@@ -41,7 +41,12 @@ RSpec.describe Async::Reactor do
|
|
41
41
|
state = :stopped
|
42
42
|
end
|
43
43
|
|
44
|
-
subject.
|
44
|
+
subject.async do |task|
|
45
|
+
task.sleep(0.1)
|
46
|
+
task.reactor.stop
|
47
|
+
end
|
48
|
+
|
49
|
+
subject.run
|
45
50
|
|
46
51
|
expect(state).to be == :started
|
47
52
|
end
|
@@ -62,4 +67,20 @@ RSpec.describe Async::Reactor do
|
|
62
67
|
|
63
68
|
expect{reactor.run}.to raise_error(RuntimeError, /closed/)
|
64
69
|
end
|
70
|
+
|
71
|
+
describe '#async' do
|
72
|
+
include_context Async::RSpec::Reactor
|
73
|
+
|
74
|
+
it "can pass in arguments" do
|
75
|
+
reactor.async(:arg) do |task, arg|
|
76
|
+
expect(arg).to be == :arg
|
77
|
+
end.wait
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#to_s' do
|
82
|
+
it "shows stopped=" do
|
83
|
+
expect(subject.to_s).to include "stopped"
|
84
|
+
end
|
85
|
+
end
|
65
86
|
end
|
data/spec/async/task_spec.rb
CHANGED
@@ -23,6 +23,39 @@ require 'benchmark'
|
|
23
23
|
RSpec.describe Async::Task do
|
24
24
|
let(:reactor) {Async::Reactor.new}
|
25
25
|
|
26
|
+
describe '#run' do
|
27
|
+
it "can't be invoked twice" do
|
28
|
+
task = reactor.async do |task|
|
29
|
+
end
|
30
|
+
|
31
|
+
expect{task.run}.to raise_error(RuntimeError, /already running/)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#async' do
|
36
|
+
it "can start child async tasks" do
|
37
|
+
child = nil
|
38
|
+
|
39
|
+
parent = reactor.async do |task|
|
40
|
+
child = task.async do
|
41
|
+
task.sleep(1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
expect(parent).to_not be_nil
|
46
|
+
expect(child).to_not be_nil
|
47
|
+
expect(child.parent).to be parent
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can pass in arguments" do
|
51
|
+
reactor.async do |task|
|
52
|
+
task.async(:arg) do |task, arg|
|
53
|
+
expect(arg).to be == :arg
|
54
|
+
end.wait
|
55
|
+
end.wait
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
26
59
|
describe '#stop' do
|
27
60
|
it "can be stopped" do
|
28
61
|
state = nil
|
@@ -95,7 +128,9 @@ RSpec.describe Async::Task do
|
|
95
128
|
reactor.run
|
96
129
|
end
|
97
130
|
|
98
|
-
|
131
|
+
# This is too unstable on travis.
|
132
|
+
# expect(time).to be_within(50).percent_of(duration)
|
133
|
+
expect(time).to be >= duration
|
99
134
|
expect(state).to be == :finished
|
100
135
|
end
|
101
136
|
end
|
@@ -182,4 +217,21 @@ RSpec.describe Async::Task do
|
|
182
217
|
expect(innocent_task).to be_finished
|
183
218
|
end
|
184
219
|
end
|
220
|
+
|
221
|
+
describe '#to_s' do
|
222
|
+
it "should show running" do
|
223
|
+
apples_task = reactor.async do |task|
|
224
|
+
task.sleep(0.1)
|
225
|
+
end
|
226
|
+
|
227
|
+
expect(apples_task.to_s).to include "running"
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should show complete" do
|
231
|
+
apples_task = reactor.async do |task|
|
232
|
+
end
|
233
|
+
|
234
|
+
expect(apples_task.to_s).to include "complete"
|
235
|
+
end
|
236
|
+
end
|
185
237
|
end
|
@@ -18,17 +18,33 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
require 'benchmark'
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
RSpec.describe Async::Wrapper do
|
24
|
+
let(:pipe) {IO.pipe}
|
25
|
+
let(:input) {Async::Wrapper.new(pipe.last)}
|
26
|
+
let(:output) {Async::Wrapper.new(pipe.first)}
|
27
|
+
|
28
|
+
describe '#wait_*' do
|
29
|
+
include_context Async::RSpec::Reactor
|
27
30
|
|
28
|
-
|
29
|
-
|
31
|
+
it "can wait for writability" do
|
32
|
+
expect(input.wait_writable(1)).to be_truthy
|
33
|
+
|
34
|
+
input.close
|
35
|
+
output.close
|
36
|
+
end
|
30
37
|
|
31
|
-
|
38
|
+
it "can wait for readability" do
|
39
|
+
reactor.async do
|
40
|
+
input.wait_writable(1)
|
41
|
+
input.io.write('Hello World')
|
42
|
+
end
|
43
|
+
|
44
|
+
expect(output.wait_readable(1)).to be_truthy
|
45
|
+
|
46
|
+
input.close
|
47
|
+
output.close
|
48
|
+
end
|
32
49
|
end
|
33
50
|
end
|
34
|
-
|
data/spec/spec_helper.rb
CHANGED
@@ -18,42 +18,9 @@ end
|
|
18
18
|
|
19
19
|
require "bundler/setup"
|
20
20
|
require "async"
|
21
|
-
require "async/tcp_socket"
|
22
|
-
require "async/udp_socket"
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
all_ios = ObjectSpace.each_object(IO).to_a.sort_by(&:object_id)
|
27
|
-
|
28
|
-
# We are not interested in ios that have been closed already:
|
29
|
-
return all_ios.reject{|io| io.closed?}
|
30
|
-
end
|
31
|
-
|
32
|
-
# We use around(:each) because it's the highest priority.
|
33
|
-
around(:each) do |example|
|
34
|
-
@system_ios = current_ios
|
35
|
-
|
36
|
-
result = example.run
|
37
|
-
|
38
|
-
expect(current_ios).to be == @system_ios
|
39
|
-
|
40
|
-
result
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
RSpec.shared_context "reactor" do
|
45
|
-
let(:reactor) {Async::Task.current.reactor}
|
46
|
-
|
47
|
-
around(:each) do |example|
|
48
|
-
Async::Reactor.run do
|
49
|
-
result = example.run
|
50
|
-
|
51
|
-
return result if result.is_a? Exception
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
include_context "closes all io"
|
56
|
-
end
|
22
|
+
# Shared rspec helpers:
|
23
|
+
require "async/rspec"
|
57
24
|
|
58
25
|
RSpec.configure do |config|
|
59
26
|
# Enable flags like --only-failures and --next-failure
|
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: 0.
|
4
|
+
version: 0.14.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: 2017-
|
11
|
+
date: 2017-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -39,47 +39,47 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '4.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: async-rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '1.
|
47
|
+
version: '1.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '1.
|
54
|
+
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: '1.3'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
68
|
+
version: '1.3'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.4
|
75
|
+
version: '3.4'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.4
|
82
|
+
version: '3.4'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,19 +113,12 @@ files:
|
|
113
113
|
- README.md
|
114
114
|
- Rakefile
|
115
115
|
- async.gemspec
|
116
|
-
- examples/aio.rb
|
117
|
-
- examples/echo.rb
|
118
116
|
- lib/async.rb
|
119
117
|
- lib/async/condition.rb
|
120
|
-
- lib/async/io.rb
|
121
118
|
- lib/async/logger.rb
|
122
119
|
- lib/async/node.rb
|
123
120
|
- lib/async/reactor.rb
|
124
|
-
- lib/async/socket.rb
|
125
121
|
- lib/async/task.rb
|
126
|
-
- lib/async/tcp_socket.rb
|
127
|
-
- lib/async/udp_socket.rb
|
128
|
-
- lib/async/unix_socket.rb
|
129
122
|
- lib/async/version.rb
|
130
123
|
- lib/async/wrapper.rb
|
131
124
|
- spec/async/condition_spec.rb
|
@@ -133,9 +126,7 @@ files:
|
|
133
126
|
- spec/async/reactor/nested_spec.rb
|
134
127
|
- spec/async/reactor_spec.rb
|
135
128
|
- spec/async/task_spec.rb
|
136
|
-
- spec/async/
|
137
|
-
- spec/async/udp_socket_spec.rb
|
138
|
-
- spec/async/unix_socket_spec.rb
|
129
|
+
- spec/async/wrapper_spec.rb
|
139
130
|
- spec/spec_helper.rb
|
140
131
|
homepage: https://github.com/socketry/async
|
141
132
|
licenses:
|
@@ -147,9 +138,9 @@ require_paths:
|
|
147
138
|
- lib
|
148
139
|
required_ruby_version: !ruby/object:Gem::Requirement
|
149
140
|
requirements:
|
150
|
-
- - "
|
141
|
+
- - "~>"
|
151
142
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.0
|
143
|
+
version: '2.0'
|
153
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
145
|
requirements:
|
155
146
|
- - ">="
|
@@ -167,7 +158,5 @@ test_files:
|
|
167
158
|
- spec/async/reactor/nested_spec.rb
|
168
159
|
- spec/async/reactor_spec.rb
|
169
160
|
- spec/async/task_spec.rb
|
170
|
-
- spec/async/
|
171
|
-
- spec/async/udp_socket_spec.rb
|
172
|
-
- spec/async/unix_socket_spec.rb
|
161
|
+
- spec/async/wrapper_spec.rb
|
173
162
|
- spec/spec_helper.rb
|