polyphony 0.45.1 → 0.45.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/TODO.md +1 -1
- data/ext/polyphony/fiber.c +66 -6
- data/ext/polyphony/polyphony.h +1 -0
- data/lib/polyphony/core/global_api.rb +2 -2
- data/lib/polyphony/extensions/fiber.rb +7 -44
- data/lib/polyphony/version.rb +1 -1
- data/test/test_fiber.rb +9 -8
- data/test/test_throttler.rb +0 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2fa4fa731ff52272d3aed456f7a26751e76c63b4335366919bffaf089bf96dd
|
4
|
+
data.tar.gz: 1afe67258c5c73d9cc1082ca238eb358dac0f5b7a975f90a77b4f6de6a23b2a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 175edf315d759f85d2c0d934be36b9fcacd68342206d984ad64f800120a8b65668e9ea81595f47cbbb439402c256b47fde78f0cdad4b42e0c3b1d6ee321135b9
|
7
|
+
data.tar.gz: 01cfe1d8b51d60a736adb80062eb22e7983a1879a5491cb7a2e47ec4ad5734e0c8bd8664653870a4393276b42fa912953721658ecff634521a672419c8d3cab6
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/TODO.md
CHANGED
data/ext/polyphony/fiber.c
CHANGED
@@ -2,12 +2,9 @@
|
|
2
2
|
|
3
3
|
ID ID_fiber_trace;
|
4
4
|
ID ID_ivar_auto_watcher;
|
5
|
-
ID
|
6
|
-
ID
|
7
|
-
ID
|
8
|
-
ID ID_trace_runnable;
|
9
|
-
ID ID_trace_terminate;
|
10
|
-
ID ID_trace_wait;
|
5
|
+
ID ID_ivar_mailbox;
|
6
|
+
ID ID_ivar_result;
|
7
|
+
ID ID_ivar_waiting_fibers;
|
11
8
|
|
12
9
|
VALUE SYM_dead;
|
13
10
|
VALUE SYM_running;
|
@@ -67,6 +64,57 @@ void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
|
67
64
|
}
|
68
65
|
}
|
69
66
|
|
67
|
+
VALUE Fiber_await(VALUE self) {
|
68
|
+
VALUE result;
|
69
|
+
|
70
|
+
// we compare with false, since a fiber that has not yet started will have
|
71
|
+
// @running set to nil
|
72
|
+
if (rb_ivar_get(self, ID_ivar_running) == Qfalse) {
|
73
|
+
result = rb_ivar_get(self, ID_ivar_result);
|
74
|
+
TEST_RESUME_EXCEPTION(result);
|
75
|
+
return result;
|
76
|
+
}
|
77
|
+
|
78
|
+
VALUE fiber = rb_fiber_current();
|
79
|
+
VALUE waiting_fibers = rb_ivar_get(self, ID_ivar_waiting_fibers);
|
80
|
+
if (waiting_fibers == Qnil) {
|
81
|
+
waiting_fibers = rb_hash_new();
|
82
|
+
rb_ivar_set(self, ID_ivar_waiting_fibers, waiting_fibers);
|
83
|
+
}
|
84
|
+
rb_hash_aset(waiting_fibers, fiber, Qtrue);
|
85
|
+
|
86
|
+
result = Thread_switch_fiber(rb_thread_current());
|
87
|
+
|
88
|
+
rb_hash_delete(waiting_fibers, fiber);
|
89
|
+
TEST_RESUME_EXCEPTION(result);
|
90
|
+
RB_GC_GUARD(result);
|
91
|
+
return result;
|
92
|
+
}
|
93
|
+
|
94
|
+
VALUE Fiber_send(VALUE self, VALUE value) {
|
95
|
+
VALUE mailbox = rb_ivar_get(self, ID_ivar_mailbox);
|
96
|
+
if (mailbox == Qnil) {
|
97
|
+
mailbox = rb_funcall(cQueue, ID_new, 0);
|
98
|
+
rb_ivar_set(self, ID_ivar_mailbox, mailbox);
|
99
|
+
}
|
100
|
+
Queue_push(mailbox, value);
|
101
|
+
return self;
|
102
|
+
}
|
103
|
+
|
104
|
+
VALUE Fiber_receive(VALUE self) {
|
105
|
+
VALUE mailbox = rb_ivar_get(self, ID_ivar_mailbox);
|
106
|
+
if (mailbox == Qnil) {
|
107
|
+
mailbox = rb_funcall(cQueue, ID_new, 0);
|
108
|
+
rb_ivar_set(self, ID_ivar_mailbox, mailbox);
|
109
|
+
}
|
110
|
+
return Queue_shift(mailbox);
|
111
|
+
}
|
112
|
+
|
113
|
+
VALUE Fiber_receive_all_pending(VALUE self) {
|
114
|
+
VALUE mailbox = rb_ivar_get(self, ID_ivar_mailbox);
|
115
|
+
return (mailbox == Qnil) ? rb_ary_new() : Queue_shift_all(mailbox);
|
116
|
+
}
|
117
|
+
|
70
118
|
void Init_Fiber() {
|
71
119
|
VALUE cFiber = rb_const_get(rb_cObject, rb_intern("Fiber"));
|
72
120
|
rb_define_method(cFiber, "safe_transfer", Fiber_safe_transfer, -1);
|
@@ -74,6 +122,15 @@ void Init_Fiber() {
|
|
74
122
|
rb_define_method(cFiber, "state", Fiber_state, 0);
|
75
123
|
rb_define_method(cFiber, "auto_watcher", Fiber_auto_watcher, 0);
|
76
124
|
|
125
|
+
rb_define_method(cFiber, "await", Fiber_await, 0);
|
126
|
+
rb_define_method(cFiber, "join", Fiber_await, 0);
|
127
|
+
|
128
|
+
rb_define_method(cFiber, "<<", Fiber_send, 1);
|
129
|
+
rb_define_method(cFiber, "send", Fiber_send, 1);
|
130
|
+
|
131
|
+
rb_define_method(cFiber, "receive", Fiber_receive, 0);
|
132
|
+
rb_define_method(cFiber, "receive_all_pending", Fiber_receive_all_pending, 0);
|
133
|
+
|
77
134
|
SYM_dead = ID2SYM(rb_intern("dead"));
|
78
135
|
SYM_running = ID2SYM(rb_intern("running"));
|
79
136
|
SYM_runnable = ID2SYM(rb_intern("runnable"));
|
@@ -85,6 +142,9 @@ void Init_Fiber() {
|
|
85
142
|
|
86
143
|
ID_fiber_trace = rb_intern("__fiber_trace__");
|
87
144
|
ID_ivar_auto_watcher = rb_intern("@auto_watcher");
|
145
|
+
ID_ivar_mailbox = rb_intern("@mailbox");
|
146
|
+
ID_ivar_result = rb_intern("@result");
|
147
|
+
ID_ivar_waiting_fibers = rb_intern("@waiting_fibers");
|
88
148
|
|
89
149
|
SYM_fiber_create = ID2SYM(rb_intern("fiber_create"));
|
90
150
|
SYM_fiber_ev_loop_enter = ID2SYM(rb_intern("fiber_ev_loop_enter"));
|
data/ext/polyphony/polyphony.h
CHANGED
@@ -72,6 +72,7 @@ void Fiber_make_runnable(VALUE fiber, VALUE value);
|
|
72
72
|
VALUE Queue_push(VALUE self, VALUE value);
|
73
73
|
VALUE Queue_unshift(VALUE self, VALUE value);
|
74
74
|
VALUE Queue_shift(VALUE self);
|
75
|
+
VALUE Queue_shift_all(VALUE self);
|
75
76
|
VALUE Queue_shift_no_wait(VALUE self);
|
76
77
|
VALUE Queue_clear(VALUE self);
|
77
78
|
VALUE Queue_delete(VALUE self, VALUE value);
|
@@ -7,20 +7,6 @@ require_relative '../core/exceptions'
|
|
7
7
|
module Polyphony
|
8
8
|
# Fiber control API
|
9
9
|
module FiberControl
|
10
|
-
def await
|
11
|
-
if @running == false
|
12
|
-
return @result.is_a?(Exception) ? (Kernel.raise @result) : @result
|
13
|
-
end
|
14
|
-
|
15
|
-
fiber = Fiber.current
|
16
|
-
@waiting_fibers ||= {}
|
17
|
-
@waiting_fibers[fiber] = true
|
18
|
-
suspend
|
19
|
-
ensure
|
20
|
-
@waiting_fibers&.delete(fiber)
|
21
|
-
end
|
22
|
-
alias_method :join, :await
|
23
|
-
|
24
10
|
def interrupt(value = nil)
|
25
11
|
return if @running == false
|
26
12
|
|
@@ -181,22 +167,6 @@ module Polyphony
|
|
181
167
|
end
|
182
168
|
end
|
183
169
|
|
184
|
-
# Messaging functionality
|
185
|
-
module FiberMessaging
|
186
|
-
def <<(value)
|
187
|
-
@mailbox << value
|
188
|
-
end
|
189
|
-
alias_method :send, :<<
|
190
|
-
|
191
|
-
def receive
|
192
|
-
@mailbox.shift
|
193
|
-
end
|
194
|
-
|
195
|
-
def receive_pending
|
196
|
-
@mailbox.shift_all
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
170
|
# Methods for controlling child fibers
|
201
171
|
module ChildFiberControl
|
202
172
|
def children
|
@@ -225,14 +195,14 @@ module Polyphony
|
|
225
195
|
def await_all_children
|
226
196
|
return unless @children && !@children.empty?
|
227
197
|
|
228
|
-
|
198
|
+
results = @children.dup
|
229
199
|
@on_child_done = proc do |c, r|
|
230
|
-
|
200
|
+
results[c] = r
|
231
201
|
schedule if @children.empty?
|
232
202
|
end
|
233
203
|
suspend
|
234
204
|
@on_child_done = nil
|
235
|
-
|
205
|
+
results.values
|
236
206
|
end
|
237
207
|
|
238
208
|
def shutdown_all_children
|
@@ -249,7 +219,6 @@ module Polyphony
|
|
249
219
|
@parent = parent
|
250
220
|
@caller = caller
|
251
221
|
@block = block
|
252
|
-
@mailbox = Polyphony::Queue.new
|
253
222
|
__fiber_trace__(:fiber_create, self)
|
254
223
|
schedule
|
255
224
|
end
|
@@ -279,7 +248,6 @@ module Polyphony
|
|
279
248
|
# allows the fiber to be scheduled and to receive messages.
|
280
249
|
def setup_raw
|
281
250
|
@thread = Thread.current
|
282
|
-
@mailbox = Polyphony::Queue.new
|
283
251
|
end
|
284
252
|
|
285
253
|
def setup_main_fiber
|
@@ -288,11 +256,10 @@ module Polyphony
|
|
288
256
|
@thread = Thread.current
|
289
257
|
@running = true
|
290
258
|
@children&.clear
|
291
|
-
@mailbox = Polyphony::Queue.new
|
292
259
|
end
|
293
260
|
|
294
261
|
def restart_self(first_value)
|
295
|
-
@mailbox =
|
262
|
+
@mailbox = nil
|
296
263
|
@when_done_procs = nil
|
297
264
|
@waiting_fibers = nil
|
298
265
|
run(first_value)
|
@@ -324,13 +291,10 @@ module Polyphony
|
|
324
291
|
def inform_dependants(result, uncaught_exception)
|
325
292
|
@parent&.child_done(self, result)
|
326
293
|
@when_done_procs&.each { |p| p.(result) }
|
327
|
-
@waiting_fibers&.each_key
|
328
|
-
|
329
|
-
end
|
330
|
-
return unless uncaught_exception && !@waiting_fibers
|
331
|
-
|
294
|
+
@waiting_fibers&.each_key { |f| f.schedule(result) }
|
295
|
+
|
332
296
|
# propagate unaught exception to parent
|
333
|
-
@parent&.schedule(result)
|
297
|
+
@parent&.schedule(result) if uncaught_exception && !@waiting_fibers
|
334
298
|
end
|
335
299
|
|
336
300
|
def when_done(&block)
|
@@ -344,7 +308,6 @@ end
|
|
344
308
|
class ::Fiber
|
345
309
|
prepend Polyphony::FiberControl
|
346
310
|
include Polyphony::FiberSupervision
|
347
|
-
include Polyphony::FiberMessaging
|
348
311
|
include Polyphony::ChildFiberControl
|
349
312
|
include Polyphony::FiberLifeCycle
|
350
313
|
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_fiber.rb
CHANGED
@@ -700,15 +700,16 @@ class FiberTest < MiniTest::Test
|
|
700
700
|
buffer = []
|
701
701
|
f = Fiber.new { buffer << receive }
|
702
702
|
|
703
|
-
|
703
|
+
assert_nil f.thread
|
704
704
|
snooze
|
705
705
|
f.setup_raw
|
706
706
|
assert_equal Thread.current, f.thread
|
707
707
|
assert_nil f.parent
|
708
708
|
|
709
709
|
f.schedule
|
710
|
+
snooze
|
710
711
|
f << 'bar'
|
711
|
-
|
712
|
+
snooze
|
712
713
|
assert_equal ['bar'], buffer
|
713
714
|
end
|
714
715
|
end
|
@@ -811,20 +812,20 @@ class MailboxTest < MiniTest::Test
|
|
811
812
|
assert_equal ['foo'] * 100, messages
|
812
813
|
end
|
813
814
|
|
814
|
-
def
|
815
|
-
assert_equal [],
|
815
|
+
def test_receive_all_pending
|
816
|
+
assert_equal [], receive_all_pending
|
816
817
|
|
817
818
|
(1..5).each { |i| Fiber.current << i }
|
818
|
-
assert_equal (1..5).to_a,
|
819
|
-
assert_equal [],
|
819
|
+
assert_equal (1..5).to_a, receive_all_pending
|
820
|
+
assert_equal [], receive_all_pending
|
820
821
|
end
|
821
822
|
|
822
|
-
def
|
823
|
+
def test_receive_all_pending_on_termination
|
823
824
|
buffer = []
|
824
825
|
worker = spin do
|
825
826
|
loop { buffer << receive }
|
826
827
|
rescue Polyphony::Terminate
|
827
|
-
|
828
|
+
receive_all_pending.each { |r| buffer << r }
|
828
829
|
end
|
829
830
|
|
830
831
|
worker << 1
|
data/test/test_throttler.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.45.
|
4
|
+
version: 0.45.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|