polyphony 0.45.1 → 0.45.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.
- 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
|