polyphony 0.22 → 0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +9 -1
- data/TODO.md +13 -38
- data/docs/summary.md +19 -5
- data/docs/technical-overview/faq.md +12 -0
- data/examples/core/01-spinning-up-coprocesses.rb +2 -6
- data/examples/core/02-awaiting-coprocesses.rb +3 -1
- data/examples/core/03-interrupting.rb +3 -1
- data/examples/core/04-no-auto-run.rb +1 -3
- data/examples/core/cancel.rb +1 -1
- data/examples/core/channel_echo.rb +3 -1
- data/examples/core/defer.rb +3 -1
- data/examples/core/enumerator.rb +3 -1
- data/examples/core/error_bubbling.rb +35 -0
- data/examples/core/fork.rb +1 -1
- data/examples/core/genserver.rb +1 -1
- data/examples/core/lock.rb +3 -1
- data/examples/core/move_on.rb +1 -1
- data/examples/core/move_on_twice.rb +1 -1
- data/examples/core/move_on_with_ensure.rb +1 -1
- data/examples/core/move_on_with_value.rb +1 -1
- data/examples/core/multiple_spin.rb +3 -1
- data/examples/core/nested_cancel.rb +1 -1
- data/examples/core/nested_multiple_spin.rb +3 -1
- data/examples/core/nested_spin.rb +3 -1
- data/examples/core/pulse.rb +1 -1
- data/examples/core/resource.rb +1 -1
- data/examples/core/resource_cancel.rb +2 -2
- data/examples/core/resource_delegate.rb +1 -1
- data/examples/core/sleep.rb +1 -1
- data/examples/core/sleep_spin.rb +3 -1
- data/examples/core/snooze.rb +1 -1
- data/examples/core/spin_error.rb +2 -1
- data/examples/core/spin_error_backtrace.rb +1 -1
- data/examples/core/spin_uncaught_error.rb +3 -1
- data/examples/core/supervisor.rb +1 -1
- data/examples/core/supervisor_with_cancel_scope.rb +1 -1
- data/examples/core/supervisor_with_error.rb +3 -1
- data/examples/core/supervisor_with_manual_move_on.rb +1 -1
- data/examples/core/suspend.rb +1 -1
- data/examples/core/thread.rb +3 -3
- data/examples/core/thread_cancel.rb +6 -3
- data/examples/core/thread_pool.rb +8 -52
- data/examples/core/thread_pool_perf.rb +63 -0
- data/examples/core/throttle.rb +3 -1
- data/examples/core/timeout.rb +1 -1
- data/examples/core/wait_for_signal.rb +4 -2
- data/examples/fs/read.rb +1 -1
- data/examples/http/http2_raw.rb +1 -1
- data/examples/http/http_get.rb +1 -1
- data/examples/http/http_server.rb +2 -1
- data/examples/http/http_server_graceful.rb +3 -1
- data/examples/http/http_ws_server.rb +0 -2
- data/examples/http/https_wss_server.rb +0 -2
- data/examples/http/websocket_secure_server.rb +0 -2
- data/examples/http/websocket_server.rb +0 -2
- data/examples/interfaces/redis_channels.rb +3 -1
- data/examples/interfaces/redis_pubsub.rb +3 -1
- data/examples/interfaces/redis_pubsub_perf.rb +3 -1
- data/examples/io/backticks.rb +1 -1
- data/examples/io/cat.rb +1 -1
- data/examples/io/echo_client.rb +1 -1
- data/examples/io/echo_client_from_stdin.rb +3 -1
- data/examples/io/echo_pipe.rb +1 -1
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_with_timeout.rb +1 -1
- data/examples/io/echo_stdin.rb +1 -1
- data/examples/io/httparty_multi.rb +1 -1
- data/examples/io/io_read.rb +1 -1
- data/examples/io/irb.rb +1 -1
- data/examples/io/net-http.rb +1 -1
- data/examples/io/open.rb +1 -1
- data/examples/io/system.rb +1 -1
- data/examples/io/tcpserver.rb +1 -1
- data/examples/io/tcpsocket.rb +1 -1
- data/examples/performance/multi_snooze.rb +1 -1
- data/examples/performance/snooze.rb +18 -10
- data/ext/gyro/async.c +16 -9
- data/ext/gyro/child.c +2 -2
- data/ext/gyro/gyro.c +17 -10
- data/ext/gyro/gyro.h +2 -2
- data/ext/gyro/io.c +2 -2
- data/ext/gyro/signal.c +33 -35
- data/ext/gyro/timer.c +6 -73
- data/lib/polyphony.rb +6 -8
- data/lib/polyphony/core/cancel_scope.rb +32 -21
- data/lib/polyphony/core/coprocess.rb +26 -23
- data/lib/polyphony/core/global_api.rb +86 -0
- data/lib/polyphony/core/resource_pool.rb +1 -1
- data/lib/polyphony/core/supervisor.rb +47 -13
- data/lib/polyphony/core/thread.rb +10 -36
- data/lib/polyphony/core/thread_pool.rb +6 -26
- data/lib/polyphony/extensions/core.rb +30 -100
- data/lib/polyphony/extensions/io.rb +10 -7
- data/lib/polyphony/extensions/openssl.rb +18 -28
- data/lib/polyphony/http/client/agent.rb +15 -11
- data/lib/polyphony/http/client/http2.rb +1 -1
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +1 -0
- data/test/coverage.rb +45 -0
- data/test/helper.rb +15 -5
- data/test/test_async.rb +4 -4
- data/test/test_cancel_scope.rb +109 -0
- data/test/test_coprocess.rb +80 -36
- data/test/{test_core.rb → test_global_api.rb} +67 -13
- data/test/test_gyro.rb +1 -5
- data/test/test_io.rb +2 -2
- data/test/test_resource_pool.rb +19 -0
- data/test/test_signal.rb +10 -5
- data/test/test_supervisor.rb +168 -0
- data/test/test_timer.rb +31 -5
- metadata +23 -4
- data/lib/polyphony/auto_run.rb +0 -19
data/examples/fs/read.rb
CHANGED
data/examples/http/http2_raw.rb
CHANGED
data/examples/http/http_get.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
require 'polyphony/http'
|
6
6
|
|
7
7
|
opts = {
|
@@ -23,3 +23,5 @@ end
|
|
23
23
|
puts "pid: #{Process.pid}"
|
24
24
|
puts 'Send HUP to stop gracefully'
|
25
25
|
puts 'Listening on port 1234...'
|
26
|
+
|
27
|
+
suspend
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
require 'polyphony/redis'
|
6
6
|
|
7
7
|
class RedisChannel < Polyphony::Channel
|
@@ -119,3 +119,5 @@ spin do
|
|
119
119
|
channel.close
|
120
120
|
RedisChannel.stop_monitor
|
121
121
|
end
|
122
|
+
|
123
|
+
suspend
|
data/examples/io/backticks.rb
CHANGED
data/examples/io/cat.rb
CHANGED
data/examples/io/echo_client.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
require 'polyphony/extensions/backtrace'
|
6
6
|
|
7
7
|
socket = Polyphony::Net.tcp_connect('127.0.0.1', 1234)
|
@@ -18,3 +18,5 @@ spin do
|
|
18
18
|
end
|
19
19
|
writer.interrupt
|
20
20
|
end
|
21
|
+
|
22
|
+
suspend
|
data/examples/io/echo_pipe.rb
CHANGED
data/examples/io/echo_server.rb
CHANGED
data/examples/io/echo_stdin.rb
CHANGED
data/examples/io/io_read.rb
CHANGED
data/examples/io/irb.rb
CHANGED
data/examples/io/net-http.rb
CHANGED
data/examples/io/open.rb
CHANGED
data/examples/io/system.rb
CHANGED
data/examples/io/tcpserver.rb
CHANGED
data/examples/io/tcpsocket.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
|
6
6
|
X = 1_000_000
|
7
7
|
|
8
|
-
STDOUT << 'Fiber.yield:
|
8
|
+
STDOUT << 'Fiber.yield: '
|
9
9
|
f = Fiber.new do
|
10
10
|
loop { Fiber.yield }
|
11
11
|
end
|
@@ -14,16 +14,24 @@ X.times { f.resume }
|
|
14
14
|
dt = Time.now - t0
|
15
15
|
puts format('%d/s', (X / dt))
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
STDOUT << 'Fiber.transfer: '
|
18
|
+
main = Fiber.current
|
19
|
+
f = Fiber.new do
|
20
|
+
loop { main.transfer }
|
21
|
+
end
|
22
|
+
t0 = Time.now
|
23
|
+
X.times { f.transfer }
|
24
|
+
dt = Time.now - t0
|
25
|
+
puts format('%d/s', (X / dt))
|
24
26
|
|
25
|
-
STDOUT << 'Kernel#snooze:
|
27
|
+
STDOUT << 'Kernel#snooze: '
|
26
28
|
t0 = Time.now
|
27
29
|
X.times { snooze }
|
28
30
|
dt = Time.now - t0
|
29
31
|
puts format('%d/s', (X / dt))
|
32
|
+
|
33
|
+
STDOUT << 'Kernel#sleep: '
|
34
|
+
t0 = Time.now
|
35
|
+
X.times { sleep(0) }
|
36
|
+
dt = Time.now - t0
|
37
|
+
puts "%d/s" % (X / dt)
|
data/ext/gyro/async.c
CHANGED
@@ -4,6 +4,7 @@ struct Gyro_Async {
|
|
4
4
|
struct ev_async ev_async;
|
5
5
|
int active;
|
6
6
|
VALUE fiber;
|
7
|
+
VALUE value;
|
7
8
|
};
|
8
9
|
|
9
10
|
static VALUE cGyro_Async = Qnil;
|
@@ -17,7 +18,7 @@ static size_t Gyro_Async_size(const void *ptr);
|
|
17
18
|
/* Methods */
|
18
19
|
static VALUE Gyro_Async_initialize(VALUE self);
|
19
20
|
|
20
|
-
static VALUE Gyro_Async_signal(VALUE self);
|
21
|
+
static VALUE Gyro_Async_signal(int argc, VALUE *argv, VALUE self);
|
21
22
|
static VALUE Gyro_Async_await(VALUE self);
|
22
23
|
|
23
24
|
void Gyro_Async_callback(struct ev_loop *ev_loop, struct ev_async *async, int revents);
|
@@ -28,7 +29,7 @@ void Init_Gyro_Async() {
|
|
28
29
|
rb_define_alloc_func(cGyro_Async, Gyro_Async_allocate);
|
29
30
|
|
30
31
|
rb_define_method(cGyro_Async, "initialize", Gyro_Async_initialize, 0);
|
31
|
-
rb_define_method(cGyro_Async, "signal!", Gyro_Async_signal,
|
32
|
+
rb_define_method(cGyro_Async, "signal!", Gyro_Async_signal, -1);
|
32
33
|
rb_define_method(cGyro_Async, "await", Gyro_Async_await, 0);
|
33
34
|
}
|
34
35
|
|
@@ -49,6 +50,9 @@ static void Gyro_Async_mark(void *ptr) {
|
|
49
50
|
if (async->fiber != Qnil) {
|
50
51
|
rb_gc_mark(async->fiber);
|
51
52
|
}
|
53
|
+
if (async->value != Qnil) {
|
54
|
+
rb_gc_mark(async->value);
|
55
|
+
}
|
52
56
|
}
|
53
57
|
|
54
58
|
static void Gyro_Async_free(void *ptr) {
|
@@ -69,6 +73,7 @@ static VALUE Gyro_Async_initialize(VALUE self) {
|
|
69
73
|
GetGyro_Async(self, async);
|
70
74
|
|
71
75
|
async->fiber = Qnil;
|
76
|
+
async->value = Qnil;
|
72
77
|
async->active = 0;
|
73
78
|
|
74
79
|
ev_async_init(&async->ev_async, Gyro_Async_callback);
|
@@ -83,16 +88,17 @@ void Gyro_Async_callback(struct ev_loop *ev_loop, struct ev_async *ev_async, int
|
|
83
88
|
async->active = 0;
|
84
89
|
|
85
90
|
if (async->fiber != Qnil) {
|
86
|
-
|
91
|
+
Gyro_schedule_fiber(async->fiber, async->value);
|
87
92
|
async->fiber = Qnil;
|
88
|
-
|
93
|
+
async->value = Qnil;
|
89
94
|
}
|
90
95
|
}
|
91
96
|
|
92
|
-
static VALUE Gyro_Async_signal(VALUE self) {
|
97
|
+
static VALUE Gyro_Async_signal(int argc, VALUE *argv, VALUE self) {
|
93
98
|
struct Gyro_Async *async;
|
94
99
|
GetGyro_Async(self, async);
|
95
100
|
|
101
|
+
async->value = (argc == 1) ? argv[0] : Qnil;
|
96
102
|
ev_async_send(EV_DEFAULT, &async->ev_async);
|
97
103
|
|
98
104
|
return Qnil;
|
@@ -110,18 +116,19 @@ static VALUE Gyro_Async_await(VALUE self) {
|
|
110
116
|
ev_async_start(EV_DEFAULT, &async->ev_async);
|
111
117
|
}
|
112
118
|
|
113
|
-
ret =
|
119
|
+
ret = Gyro_await();
|
114
120
|
|
115
121
|
// fiber is resumed
|
116
|
-
async->fiber = Qnil;
|
117
122
|
if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
|
118
123
|
if (async->active) {
|
119
124
|
async->active = 0;
|
120
125
|
ev_async_stop(EV_DEFAULT, &async->ev_async);
|
126
|
+
async->fiber = Qnil;
|
127
|
+
async->value = Qnil;
|
121
128
|
}
|
122
|
-
return rb_funcall(
|
129
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, ret);
|
123
130
|
}
|
124
131
|
else {
|
125
|
-
return
|
132
|
+
return ret;
|
126
133
|
}
|
127
134
|
}
|