polyphony 0.17 → 0.19
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/CHANGELOG.md +15 -0
- data/Gemfile.lock +11 -3
- data/README.md +18 -18
- data/TODO.md +5 -21
- data/examples/core/channel_echo.rb +3 -3
- data/examples/core/enumerator.rb +1 -1
- data/examples/core/fork.rb +1 -1
- data/examples/core/genserver.rb +1 -1
- data/examples/core/lock.rb +3 -3
- data/examples/core/multiple_spawn.rb +2 -2
- data/examples/core/nested_async.rb +1 -1
- data/examples/core/nested_multiple_spawn.rb +3 -3
- data/examples/core/resource_cancel.rb +1 -1
- data/examples/core/sleep_spawn.rb +2 -2
- data/examples/core/spawn.rb +1 -1
- data/examples/core/spawn_cancel.rb +1 -1
- data/examples/core/spawn_error.rb +4 -4
- data/examples/core/supervisor.rb +1 -1
- data/examples/core/supervisor_with_error.rb +1 -1
- data/examples/core/supervisor_with_manual_move_on.rb +1 -1
- data/examples/core/thread.rb +2 -2
- data/examples/core/thread_cancel.rb +2 -2
- data/examples/core/thread_pool.rb +1 -1
- data/examples/core/throttle.rb +3 -3
- data/examples/core/timeout.rb +10 -0
- data/examples/fs/read.rb +1 -1
- data/examples/http/http_client.rb +1 -1
- data/examples/http/http_get.rb +7 -0
- data/examples/http/http_parse_experiment.rb +118 -0
- data/examples/http/http_proxy.rb +81 -0
- data/examples/http/http_server.rb +15 -4
- data/examples/http/http_server_forked.rb +2 -2
- data/examples/http/http_server_throttled.rb +1 -1
- data/examples/http/http_ws_server.rb +2 -2
- data/examples/http/https_server.rb +5 -1
- data/examples/http/https_wss_server.rb +1 -1
- data/examples/http/rack_server_https_forked.rb +1 -1
- data/examples/interfaces/pg_client.rb +1 -1
- data/examples/interfaces/pg_pool.rb +1 -1
- data/examples/interfaces/redis_channels.rb +5 -5
- data/examples/interfaces/redis_pubsub.rb +2 -2
- data/examples/interfaces/redis_pubsub_perf.rb +3 -3
- data/examples/io/echo_client.rb +2 -2
- data/examples/io/echo_pipe.rb +17 -0
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_with_timeout.rb +1 -1
- data/examples/io/httparty.rb +10 -0
- data/examples/io/httparty_multi.rb +29 -0
- data/examples/io/httparty_threaded.rb +25 -0
- data/examples/io/irb.rb +15 -0
- data/examples/io/net-http.rb +15 -0
- data/examples/io/system.rb +1 -1
- data/examples/io/tcpsocket.rb +18 -0
- data/examples/performance/perf_multi_snooze.rb +2 -2
- data/examples/performance/perf_snooze.rb +17 -20
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -1
- data/ext/ev/ev.h +9 -1
- data/ext/ev/ev_ext.c +4 -1
- data/ext/ev/ev_module.c +36 -22
- data/ext/ev/extconf.rb +1 -1
- data/ext/ev/io.c +23 -23
- data/ext/ev/signal.c +1 -1
- data/ext/ev/socket.c +161 -0
- data/lib/polyphony/core/coprocess.rb +1 -1
- data/lib/polyphony/core/fiber_pool.rb +2 -2
- data/lib/polyphony/core/supervisor.rb +2 -18
- data/lib/polyphony/extensions/io.rb +19 -6
- data/lib/polyphony/extensions/kernel.rb +17 -5
- data/lib/polyphony/extensions/socket.rb +40 -1
- data/lib/polyphony/http/agent.rb +56 -25
- data/lib/polyphony/http/http1_adapter.rb +254 -0
- data/lib/polyphony/http/http2_adapter.rb +157 -0
- data/lib/polyphony/http/{http2_request.rb → request.rb} +25 -22
- data/lib/polyphony/http/server.rb +19 -11
- data/lib/polyphony/net.rb +10 -6
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +6 -5
- data/test/test_coprocess.rb +9 -9
- data/test/test_core.rb +14 -14
- data/test/test_io.rb +4 -4
- data/test/test_kernel.rb +1 -1
- metadata +48 -23
- data/lib/polyphony/http/http1.rb +0 -124
- data/lib/polyphony/http/http1_request.rb +0 -83
- data/lib/polyphony/http/http2.rb +0 -65
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
export_default :Protocol
|
4
|
+
|
5
|
+
require 'http/2'
|
6
|
+
|
7
|
+
Request = import('./request')
|
8
|
+
|
9
|
+
class StreamWrapper
|
10
|
+
def initialize(stream, parse_fiber)
|
11
|
+
@stream = stream
|
12
|
+
@parse_fiber = parse_fiber
|
13
|
+
@parsing = true
|
14
|
+
|
15
|
+
stream.on(:data) { |data| on_body(data) }
|
16
|
+
stream.on(:half_close) { on_message_complete }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Reads body chunk from connection
|
20
|
+
def get_body_chunk
|
21
|
+
@calling_fiber = Fiber.current
|
22
|
+
@read_body = true
|
23
|
+
@parse_fiber.safe_transfer
|
24
|
+
end
|
25
|
+
|
26
|
+
# Wait for request to finish
|
27
|
+
def consume_request
|
28
|
+
return unless @parsing
|
29
|
+
|
30
|
+
@calling_fiber = Fiber.current
|
31
|
+
@read_body = false
|
32
|
+
@parse_fiber.safe_transfer while @parsing
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_body(data)
|
36
|
+
@calling_fiber.transfer(data) if @read_body
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_message_complete
|
40
|
+
@parsing = false
|
41
|
+
@calling_fiber.transfer nil
|
42
|
+
end
|
43
|
+
|
44
|
+
# response API
|
45
|
+
def respond(chunk, headers)
|
46
|
+
consume_request if @parsing
|
47
|
+
|
48
|
+
headers[':status'] ||= '200'
|
49
|
+
@stream.headers(headers, end_stream: false)
|
50
|
+
@stream.data(chunk, end_stream: true)
|
51
|
+
@headers_sent = true
|
52
|
+
end
|
53
|
+
|
54
|
+
def send_headers(headers, empty_response = false)
|
55
|
+
return if @headers_sent
|
56
|
+
|
57
|
+
consume_request if @parsing
|
58
|
+
|
59
|
+
headers[':status'] ||= (empty_response ? 204 : 200).to_s
|
60
|
+
@stream.headers(headers, end_stream: false)
|
61
|
+
@headers_sent = true
|
62
|
+
end
|
63
|
+
|
64
|
+
def send_body_chunk(chunk, done: false)
|
65
|
+
send_headers({}, false) unless @headers_sent
|
66
|
+
@stream.data(chunk, end_stream: done)
|
67
|
+
end
|
68
|
+
|
69
|
+
def finish
|
70
|
+
consume_request if @parsing
|
71
|
+
|
72
|
+
unless @headers_sent
|
73
|
+
headers[':status'] ||= '204'
|
74
|
+
@stream.headers(headers, end_stream: true)
|
75
|
+
else
|
76
|
+
@stream.close
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Protocol
|
82
|
+
def self.upgrade_each(socket, opts, headers, &block)
|
83
|
+
adapter = new(socket, opts, headers)
|
84
|
+
adapter.each(&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize(conn, opts, upgrade_headers = nil)
|
88
|
+
@conn = conn
|
89
|
+
@opts = opts
|
90
|
+
|
91
|
+
@interface = ::HTTP2::Server.new
|
92
|
+
@interface.on(:frame) { |bytes| conn << bytes }
|
93
|
+
@interface.on(:stream) { |stream| start_stream(stream) }
|
94
|
+
@parse_fiber = Fiber.new { parse_loop(upgrade_headers) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def start_stream(stream)
|
98
|
+
stream.on(:headers) do |headers|
|
99
|
+
@calling_fiber.transfer([stream, headers.to_h])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def protocol
|
104
|
+
'h2'
|
105
|
+
end
|
106
|
+
|
107
|
+
def parse_loop(upgrade_headers)
|
108
|
+
upgrade(upgrade_headers) if upgrade_headers
|
109
|
+
|
110
|
+
while (data = @conn.readpartial(8192))
|
111
|
+
@interface << data
|
112
|
+
snooze
|
113
|
+
end
|
114
|
+
@calling_fiber.transfer nil
|
115
|
+
rescue SystemCallError, IOError
|
116
|
+
# ignore
|
117
|
+
@calling_fiber.transfer nil
|
118
|
+
rescue => error
|
119
|
+
# an error return value will be raised by the receiving fiber
|
120
|
+
@calling_fiber.transfer error
|
121
|
+
end
|
122
|
+
|
123
|
+
# request API
|
124
|
+
|
125
|
+
UPGRADE_MESSAGE = <<~HTTP.gsub("\n", "\r\n")
|
126
|
+
HTTP/1.1 101 Switching Protocols
|
127
|
+
Connection: Upgrade
|
128
|
+
Upgrade: h2c
|
129
|
+
|
130
|
+
HTTP
|
131
|
+
|
132
|
+
def upgrade(headers)
|
133
|
+
settings = headers['HTTP2-Settings']
|
134
|
+
@conn << UPGRADE_MESSAGE
|
135
|
+
@interface.upgrade(settings, headers, '')
|
136
|
+
end
|
137
|
+
|
138
|
+
# Iterates over incoming requests
|
139
|
+
def each(&block)
|
140
|
+
can_upgrade = true
|
141
|
+
while @parse_fiber.alive?
|
142
|
+
stream, headers = get_headers
|
143
|
+
break unless stream
|
144
|
+
wrapper = StreamWrapper.new(stream, @parse_fiber)
|
145
|
+
request = Request.new(headers, wrapper)
|
146
|
+
Fiber.new { block.(request) }.resume
|
147
|
+
end
|
148
|
+
ensure
|
149
|
+
@conn.close rescue nil
|
150
|
+
end
|
151
|
+
|
152
|
+
# Reads headers from connection
|
153
|
+
def get_headers
|
154
|
+
@calling_fiber = Fiber.current
|
155
|
+
@parse_fiber.safe_transfer
|
156
|
+
end
|
157
|
+
end
|
@@ -5,24 +5,15 @@ export_default :Request
|
|
5
5
|
require 'uri'
|
6
6
|
|
7
7
|
class Request
|
8
|
-
|
9
|
-
@stream = stream
|
10
|
-
end
|
8
|
+
attr_reader :headers, :adapter
|
11
9
|
|
12
|
-
def
|
13
|
-
|
10
|
+
def initialize(headers, adapter)
|
11
|
+
@headers = headers
|
12
|
+
@adapter = adapter
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
@
|
18
|
-
end
|
19
|
-
|
20
|
-
def add_body_chunk(chunk)
|
21
|
-
if @body
|
22
|
-
@body << chunk
|
23
|
-
else
|
24
|
-
@body = +chunk
|
25
|
-
end
|
15
|
+
def protocol
|
16
|
+
@adapter.protocol
|
26
17
|
end
|
27
18
|
|
28
19
|
def method
|
@@ -33,16 +24,19 @@ class Request
|
|
33
24
|
@scheme ||= @headers[':scheme']
|
34
25
|
end
|
35
26
|
|
36
|
-
def
|
27
|
+
def uri
|
37
28
|
@uri ||= URI.parse(@headers[':path'] || '')
|
38
|
-
|
29
|
+
end
|
30
|
+
|
31
|
+
def path
|
32
|
+
@path ||= uri.path
|
39
33
|
end
|
40
34
|
|
41
35
|
def query
|
42
36
|
@uri ||= URI.parse(@headers[':path'] || '')
|
43
37
|
return @query if @query
|
44
38
|
|
45
|
-
if (q =
|
39
|
+
if (q = uri.query)
|
46
40
|
@query = q.split('&').each_with_object({}) do |kv, h|
|
47
41
|
k, v = kv.split('=')
|
48
42
|
h[k.to_sym] = URI.decode_www_form_component(v)
|
@@ -54,10 +48,19 @@ class Request
|
|
54
48
|
|
55
49
|
EMPTY_HASH = {}
|
56
50
|
|
57
|
-
def respond(
|
58
|
-
headers
|
51
|
+
def respond(chunk, headers = EMPTY_HASH)
|
52
|
+
@adapter.respond(chunk, headers)
|
53
|
+
end
|
54
|
+
|
55
|
+
def send_headers(headers = EMPTY_HASH, empty_response = false)
|
56
|
+
@adapter.send_headers(headers, empty_response)
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_body_chunk(body, done: false)
|
60
|
+
@adapter.send_body_chunk(body, done: done)
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
@
|
63
|
+
def finish
|
64
|
+
@adapter.finish
|
62
65
|
end
|
63
66
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
export :serve, :listen, :accept_loop
|
4
4
|
|
5
5
|
Net = import('../net')
|
6
|
-
HTTP1 = import('./
|
7
|
-
HTTP2 = import('./
|
6
|
+
HTTP1 = import('./http1_adapter')
|
7
|
+
HTTP2 = import('./http2_adapter')
|
8
8
|
|
9
9
|
ALPN_PROTOCOLS = %w[h2 http/1.1].freeze
|
10
10
|
H2_PROTOCOL = 'h2'
|
@@ -17,25 +17,33 @@ end
|
|
17
17
|
|
18
18
|
def listen(host, port, opts = {})
|
19
19
|
opts[:alpn_protocols] = ALPN_PROTOCOLS
|
20
|
-
Net.tcp_listen(host, port, opts)
|
20
|
+
Net.tcp_listen(host, port, opts).tap do |socket|
|
21
|
+
socket.define_singleton_method(:each) do |&block|
|
22
|
+
MODULE.accept_loop(socket, opts, &block)
|
23
|
+
end
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
27
|
def accept_loop(server, opts, &handler)
|
24
|
-
|
28
|
+
loop do
|
25
29
|
client = server.accept
|
26
|
-
|
30
|
+
spin { client_loop(client, opts, &handler) }
|
31
|
+
rescue OpenSSL::SSL::SSLError
|
32
|
+
# disregard
|
27
33
|
end
|
28
|
-
rescue OpenSSL::SSL::SSLError
|
29
|
-
retry # disregard
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
36
|
+
def client_loop(client, opts, &handler)
|
33
37
|
client.no_delay rescue nil
|
34
|
-
|
38
|
+
adapter = protocol_adapter(client, opts)
|
39
|
+
adapter.each(&handler)
|
40
|
+
ensure
|
41
|
+
client.close rescue nil
|
35
42
|
end
|
36
43
|
|
37
|
-
def
|
44
|
+
def protocol_adapter(socket, opts)
|
38
45
|
use_http2 = socket.respond_to?(:alpn_protocol) &&
|
39
46
|
socket.alpn_protocol == H2_PROTOCOL
|
40
|
-
use_http2 ? HTTP2 : HTTP1
|
47
|
+
klass = use_http2 ? HTTP2 : HTTP1
|
48
|
+
klass.new(socket, opts)
|
41
49
|
end
|
data/lib/polyphony/net.rb
CHANGED
@@ -12,7 +12,7 @@ def tcp_connect(host, port, opts = {})
|
|
12
12
|
s.connect(addr)
|
13
13
|
}
|
14
14
|
if opts[:secure_context] || opts[:secure]
|
15
|
-
secure_socket(socket, opts[:secure_context], opts)
|
15
|
+
secure_socket(socket, opts[:secure_context], opts.merge(host: host))
|
16
16
|
else
|
17
17
|
socket
|
18
18
|
end
|
@@ -36,11 +36,15 @@ def tcp_listen(host = nil, port = nil, opts = {})
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def secure_socket(socket, context, opts)
|
39
|
-
if context
|
40
|
-
|
41
|
-
OpenSSL::SSL::SSLSocket.new(socket, context)
|
42
|
-
|
43
|
-
|
39
|
+
setup_alpn(context, opts[:alpn_protocols]) if context && opts[:alpn_protocols]
|
40
|
+
socket = context ?
|
41
|
+
OpenSSL::SSL::SSLSocket.new(socket, context) :
|
42
|
+
OpenSSL::SSL::SSLSocket.new(socket)
|
43
|
+
|
44
|
+
socket.tap do |s|
|
45
|
+
s.hostname = opts[:host] if opts[:host]
|
46
|
+
s.connect
|
47
|
+
s.post_connection_check(opts[:host]) if opts[:host]
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
data/lib/polyphony/version.rb
CHANGED
data/polyphony.gemspec
CHANGED
@@ -17,16 +17,17 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.extensions = ["ext/ev/extconf.rb"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_runtime_dependency 'modulation', '0.
|
20
|
+
s.add_runtime_dependency 'modulation', '~>0.25'
|
21
21
|
|
22
22
|
s.add_runtime_dependency 'http_parser.rb', '0.6.0'
|
23
23
|
s.add_runtime_dependency 'http-2', '0.10.0'
|
24
24
|
|
25
|
-
s.add_development_dependency '
|
26
|
-
s.add_development_dependency '
|
25
|
+
s.add_development_dependency 'hiredis', '0.6.3'
|
26
|
+
s.add_development_dependency 'httparty', '0.17.0'
|
27
27
|
s.add_development_dependency 'localhost', '1.1.4'
|
28
|
-
s.add_development_dependency '
|
28
|
+
s.add_development_dependency 'minitest', '5.11.3'
|
29
29
|
s.add_development_dependency 'pg', '1.1.3'
|
30
|
+
s.add_development_dependency 'rake-compiler', '1.0.5'
|
30
31
|
s.add_development_dependency 'redis', '4.1.0'
|
31
|
-
s.add_development_dependency '
|
32
|
+
s.add_development_dependency 'websocket', '1.2.8'
|
32
33
|
end
|
data/test/test_coprocess.rb
CHANGED
@@ -86,7 +86,7 @@ class CoprocessTest < MiniTest::Test
|
|
86
86
|
|
87
87
|
def test_that_coprocess_can_be_awaited
|
88
88
|
result = nil
|
89
|
-
|
89
|
+
spin do
|
90
90
|
coprocess = Polyphony::Coprocess.new { sleep(0.001); 42 }
|
91
91
|
result = coprocess.await
|
92
92
|
end
|
@@ -96,7 +96,7 @@ class CoprocessTest < MiniTest::Test
|
|
96
96
|
|
97
97
|
def test_that_coprocess_can_be_stopped
|
98
98
|
result = nil
|
99
|
-
coprocess =
|
99
|
+
coprocess = spin do
|
100
100
|
sleep(0.001)
|
101
101
|
result = 42
|
102
102
|
end
|
@@ -107,7 +107,7 @@ class CoprocessTest < MiniTest::Test
|
|
107
107
|
|
108
108
|
def test_that_coprocess_can_be_cancelled
|
109
109
|
result = nil
|
110
|
-
coprocess =
|
110
|
+
coprocess = spin do
|
111
111
|
sleep(0.001)
|
112
112
|
result = 42
|
113
113
|
rescue Polyphony::Cancel => e
|
@@ -125,8 +125,8 @@ class CoprocessTest < MiniTest::Test
|
|
125
125
|
def test_that_inner_coprocess_can_be_interrupted
|
126
126
|
result = nil
|
127
127
|
coprocess2 = nil
|
128
|
-
coprocess =
|
129
|
-
coprocess2 =
|
128
|
+
coprocess = spin do
|
129
|
+
coprocess2 = spin do
|
130
130
|
sleep(0.001)
|
131
131
|
result = 42
|
132
132
|
end
|
@@ -143,8 +143,8 @@ class CoprocessTest < MiniTest::Test
|
|
143
143
|
def test_that_inner_coprocess_can_interrupt_outer_coprocess
|
144
144
|
result, coprocess2 = nil
|
145
145
|
|
146
|
-
coprocess =
|
147
|
-
coprocess2 =
|
146
|
+
coprocess = spin do
|
147
|
+
coprocess2 = spin do
|
148
148
|
EV.next_tick { coprocess.interrupt }
|
149
149
|
sleep(0.001)
|
150
150
|
result = 42
|
@@ -168,7 +168,7 @@ class MailboxTest < MiniTest::Test
|
|
168
168
|
|
169
169
|
def test_that_coprocess_can_receive_messages
|
170
170
|
msgs = []
|
171
|
-
coprocess =
|
171
|
+
coprocess = spin {
|
172
172
|
loop {
|
173
173
|
msgs << receive
|
174
174
|
}
|
@@ -185,7 +185,7 @@ class MailboxTest < MiniTest::Test
|
|
185
185
|
|
186
186
|
def test_that_multiple_messages_sent_at_once_arrive
|
187
187
|
msgs = []
|
188
|
-
coprocess =
|
188
|
+
coprocess = spin {
|
189
189
|
loop {
|
190
190
|
msgs << receive
|
191
191
|
}
|
data/test/test_core.rb
CHANGED
@@ -9,7 +9,7 @@ class SpawnTest < MiniTest::Test
|
|
9
9
|
|
10
10
|
def test_that_spawn_returns_a_coprocess
|
11
11
|
result = nil
|
12
|
-
coprocess =
|
12
|
+
coprocess = spin { result = 42 }
|
13
13
|
|
14
14
|
assert_kind_of(Polyphony::Coprocess, coprocess)
|
15
15
|
assert_nil(result)
|
@@ -20,7 +20,7 @@ class SpawnTest < MiniTest::Test
|
|
20
20
|
def test_that_spawn_accepts_coprocess_argument
|
21
21
|
result = nil
|
22
22
|
coprocess = Polyphony::Coprocess.new { result = 42 }
|
23
|
-
|
23
|
+
spin coprocess
|
24
24
|
|
25
25
|
assert_nil(result)
|
26
26
|
suspend
|
@@ -28,7 +28,7 @@ class SpawnTest < MiniTest::Test
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_that_spawned_coprocess_saves_result
|
31
|
-
coprocess =
|
31
|
+
coprocess = spin { 42 }
|
32
32
|
|
33
33
|
assert_kind_of(Polyphony::Coprocess, coprocess)
|
34
34
|
assert_nil(coprocess.result)
|
@@ -38,7 +38,7 @@ class SpawnTest < MiniTest::Test
|
|
38
38
|
|
39
39
|
def test_that_spawned_coprocess_can_be_interrupted
|
40
40
|
result = nil
|
41
|
-
coprocess =
|
41
|
+
coprocess = spin { sleep(1); 42 }
|
42
42
|
EV.next_tick { coprocess.interrupt }
|
43
43
|
suspend
|
44
44
|
assert_nil(coprocess.result)
|
@@ -59,7 +59,7 @@ class CancelScopeTest < Minitest::Test
|
|
59
59
|
|
60
60
|
def test_that_cancel_scope_cancels_coprocess
|
61
61
|
ctx = {}
|
62
|
-
|
62
|
+
spin do
|
63
63
|
EV::Timer.new(0.005, 0).start { ctx[:cancel_scope]&.cancel! }
|
64
64
|
sleep_with_cancel(ctx, :cancel)
|
65
65
|
rescue Exception => e
|
@@ -76,7 +76,7 @@ class CancelScopeTest < Minitest::Test
|
|
76
76
|
|
77
77
|
# def test_that_cancel_scope_cancels_async_op_with_stop
|
78
78
|
# ctx = {}
|
79
|
-
#
|
79
|
+
# spin do
|
80
80
|
# EV::Timer.new(0, 0).start { ctx[:cancel_scope].cancel! }
|
81
81
|
# sleep_with_cancel(ctx, :stop)
|
82
82
|
# end
|
@@ -88,7 +88,7 @@ class CancelScopeTest < Minitest::Test
|
|
88
88
|
|
89
89
|
def test_that_cancel_after_raises_cancelled_exception
|
90
90
|
result = nil
|
91
|
-
|
91
|
+
spin do
|
92
92
|
cancel_after(0.01) do
|
93
93
|
sleep(1000)
|
94
94
|
end
|
@@ -103,7 +103,7 @@ class CancelScopeTest < Minitest::Test
|
|
103
103
|
def test_that_cancel_scopes_can_be_nested
|
104
104
|
inner_result = nil
|
105
105
|
outer_result = nil
|
106
|
-
|
106
|
+
spin do
|
107
107
|
move_on_after(0.01) do
|
108
108
|
move_on_after(0.02) do
|
109
109
|
sleep(1000)
|
@@ -119,7 +119,7 @@ class CancelScopeTest < Minitest::Test
|
|
119
119
|
EV.rerun
|
120
120
|
|
121
121
|
outer_result = nil
|
122
|
-
|
122
|
+
spin do
|
123
123
|
move_on_after(0.02) do
|
124
124
|
move_on_after(0.01) do
|
125
125
|
sleep(1000)
|
@@ -148,13 +148,13 @@ class SupervisorTest < MiniTest::Test
|
|
148
148
|
|
149
149
|
def parallel_sleep(ctx)
|
150
150
|
supervise do |s|
|
151
|
-
(1..3).each { |idx| s.
|
151
|
+
(1..3).each { |idx| s.spin sleep_and_set(ctx, idx) }
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
def test_that_supervisor_waits_for_all_nested_coprocesses_to_complete
|
156
156
|
ctx = {}
|
157
|
-
|
157
|
+
spin do
|
158
158
|
parallel_sleep(ctx)
|
159
159
|
end
|
160
160
|
suspend
|
@@ -165,12 +165,12 @@ class SupervisorTest < MiniTest::Test
|
|
165
165
|
|
166
166
|
def test_that_supervisor_can_add_coprocesses_after_having_started
|
167
167
|
result = []
|
168
|
-
|
168
|
+
spin {
|
169
169
|
supervisor = Polyphony::Supervisor.new
|
170
170
|
3.times do |i|
|
171
|
-
|
171
|
+
spin do
|
172
172
|
sleep(0.001)
|
173
|
-
supervisor.
|
173
|
+
supervisor.spin do
|
174
174
|
sleep(0.001)
|
175
175
|
result << i
|
176
176
|
end
|