polyphony 0.99.5 → 1.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/.rubocop.yml +1 -0
- data/.yardopts +0 -2
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/docs/readme.md +1 -1
- data/docs/tutorial.md +2 -2
- data/ext/polyphony/fiber.c +1 -1
- data/ext/polyphony/pipe.c +0 -2
- data/ext/polyphony/polyphony.c +9 -11
- data/ext/polyphony/queue.c +0 -2
- data/ext/polyphony/thread.c +1 -1
- data/lib/polyphony/adapters/process.rb +1 -3
- data/lib/polyphony/core/debug.rb +0 -3
- data/lib/polyphony/core/exceptions.rb +0 -4
- data/lib/polyphony/core/sync.rb +4 -6
- data/lib/polyphony/core/thread_pool.rb +1 -5
- data/lib/polyphony/core/timer.rb +0 -6
- data/lib/polyphony/extensions/fiber.rb +14 -11
- data/lib/polyphony/extensions/io.rb +2 -2
- data/lib/polyphony/extensions/object.rb +283 -2
- data/lib/polyphony/extensions/openssl.rb +3 -3
- data/lib/polyphony/extensions/pipe.rb +2 -2
- data/lib/polyphony/extensions/socket.rb +9 -9
- data/lib/polyphony/extensions/thread.rb +3 -5
- data/lib/polyphony/net.rb +0 -1
- data/lib/polyphony/version.rb +1 -1
- metadata +5 -9
- data/docs/index.md +0 -94
- data/docs/link_rewriter.rb +0 -17
- data/docs/main-concepts/index.md +0 -9
- data/lib/polyphony/core/global_api.rb +0 -295
- /data/{assets → docs/assets}/echo-fibers.svg +0 -0
- /data/{assets → docs/assets}/polyphony-logo.png +0 -0
- /data/{assets → docs/assets}/sleeping-fiber.svg +0 -0
@@ -1,8 +1,289 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../core/
|
3
|
+
require_relative '../core/throttler'
|
4
4
|
|
5
5
|
# Object extensions (methods available to all objects / call sites)
|
6
6
|
class ::Object
|
7
|
-
|
7
|
+
# Spins up a fiber that will run the given block after sleeping for the
|
8
|
+
# given delay.
|
9
|
+
#
|
10
|
+
# @param interval [Number] delay in seconds before running the given block
|
11
|
+
# @return [Fiber] spun fiber
|
12
|
+
def after(interval, &block)
|
13
|
+
spin do
|
14
|
+
sleep interval
|
15
|
+
block.()
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Runs the given block after setting up a cancellation timer for
|
20
|
+
# cancellation. If the cancellation timer elapses, the execution will be
|
21
|
+
# interrupted with an exception defaulting to `Polyphony::Cancel`.
|
22
|
+
#
|
23
|
+
# This method should be used when a timeout should cause an exception to be
|
24
|
+
# propagated down the call stack or up the fiber tree.
|
25
|
+
#
|
26
|
+
# Example of normal use:
|
27
|
+
#
|
28
|
+
# def read_from_io_with_timeout(io)
|
29
|
+
# cancel_after(10) { io.read }
|
30
|
+
# rescue Polyphony::Cancel
|
31
|
+
# nil
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# The timeout period can be reset by passing a block that takes a single
|
35
|
+
# argument. The block will be provided with the canceller fiber. To reset
|
36
|
+
# the timeout, use `Fiber#reset`, as shown in the following example:
|
37
|
+
#
|
38
|
+
# cancel_after(10) do |timeout|
|
39
|
+
# loop do
|
40
|
+
# msg = socket.gets
|
41
|
+
# timeout.reset
|
42
|
+
# handle_msg(msg)
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# @overload cancel_after(interval)
|
47
|
+
# @param interval [Number] timout in seconds
|
48
|
+
# @yield [Fiber] timeout fiber
|
49
|
+
# @return [any] block's return value
|
50
|
+
# @overload cancel_after(interval, with_exception: exception)
|
51
|
+
# @param interval [Number] timout in seconds
|
52
|
+
# @param with_exception [Class, Exception] exception or exception class
|
53
|
+
# @yield [Fiber] timeout fiber
|
54
|
+
# @return [any] block's return value
|
55
|
+
# @overload cancel_after(interval, with_exception: [klass, message])
|
56
|
+
# @param interval [Number] timout in seconds
|
57
|
+
# @param with_exception [Array] array containing class and message to use as exception
|
58
|
+
# @yield [Fiber] timeout fiber
|
59
|
+
# @return [any] block's return value
|
60
|
+
def cancel_after(interval, with_exception: Polyphony::Cancel, &block)
|
61
|
+
if block.arity > 0
|
62
|
+
cancel_after_with_optional_reset(interval, with_exception, &block)
|
63
|
+
else
|
64
|
+
Polyphony.backend_timeout(interval, with_exception, &block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Spins up a new fiber.
|
69
|
+
#
|
70
|
+
# @param tag [any] optional tag for the new fiber
|
71
|
+
# @return [Fiber] new fiber
|
72
|
+
def spin(tag = nil, &block)
|
73
|
+
Fiber.current.spin(tag, caller, &block)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Spins up a new fiber, running the given block inside an infinite loop. If
|
77
|
+
# `rate:` or `interval:` parameters are given, the loop is throttled
|
78
|
+
# accordingly.
|
79
|
+
#
|
80
|
+
# @param tag [any] optional tag for the new fiber
|
81
|
+
# @param rate [Number, nil] loop rate (times per second)
|
82
|
+
# @param interval [Number, nil] interval between consecutive iterations in seconds
|
83
|
+
# @return [Fiber] new fiber
|
84
|
+
def spin_loop(tag = nil, rate: nil, interval: nil, &block)
|
85
|
+
if rate || interval
|
86
|
+
Fiber.current.spin(tag, caller) do
|
87
|
+
throttled_loop(rate: rate, interval: interval, &block)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
spin_loop_without_throttling(tag, caller, block)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Runs the given code, then waits for any child fibers of the current fibers
|
95
|
+
# to terminate.
|
96
|
+
#
|
97
|
+
# @return [any] given block's return value
|
98
|
+
def spin_scope(&block)
|
99
|
+
raise unless block
|
100
|
+
|
101
|
+
spin do
|
102
|
+
result = yield
|
103
|
+
Fiber.current.await_all_children
|
104
|
+
result
|
105
|
+
end.await
|
106
|
+
end
|
107
|
+
|
108
|
+
# Runs the given block in an infinite loop with a regular interval between
|
109
|
+
# consecutive iterations.
|
110
|
+
#
|
111
|
+
# @param interval [Number] interval between consecutive iterations in seconds
|
112
|
+
def every(interval, &block)
|
113
|
+
Polyphony.backend_timer_loop(interval, &block)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Runs the given block after setting up a cancellation timer for
|
117
|
+
# cancellation. If the cancellation timer elapses, the execution will be
|
118
|
+
# interrupted with a `Polyphony::MoveOn` exception, which will be rescued,
|
119
|
+
# and with cause the operation to return the given value.
|
120
|
+
#
|
121
|
+
# This method should be used when a timeout is to be handled locally,
|
122
|
+
# without generating an exception that is to propagated down the call stack
|
123
|
+
# or up the fiber tree.
|
124
|
+
#
|
125
|
+
# Example of normal use:
|
126
|
+
#
|
127
|
+
# move_on_after(10) {
|
128
|
+
# sleep 60
|
129
|
+
# 42
|
130
|
+
# } #=> nil
|
131
|
+
#
|
132
|
+
# move_on_after(10, with_value: :oops) {
|
133
|
+
# sleep 60
|
134
|
+
# 42
|
135
|
+
# } #=> :oops
|
136
|
+
#
|
137
|
+
# The timeout period can be reset by passing a block that takes a single
|
138
|
+
# argument. The block will be provided with the canceller fiber. To reset
|
139
|
+
# the timeout, use `Fiber#reset`, as shown in the following example:
|
140
|
+
#
|
141
|
+
# move_on_after(10) do |timeout|
|
142
|
+
# loop do
|
143
|
+
# msg = socket.gets
|
144
|
+
# timeout.reset
|
145
|
+
# handle_msg(msg)
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# @overload move_on_after(interval) { ... }
|
150
|
+
# @param interval [Number] timout in seconds
|
151
|
+
# @yield [Fiber] timeout fiber
|
152
|
+
# @return [any] block's return value
|
153
|
+
# @overload move_on_after(interval, with_value: value) { ... }
|
154
|
+
# @param interval [Number] timout in seconds
|
155
|
+
# @param with_value [any] return value in case of timeout
|
156
|
+
# @yield [Fiber] timeout fiber
|
157
|
+
# @return [any] block's return value
|
158
|
+
def move_on_after(interval, with_value: nil, &block)
|
159
|
+
if block.arity > 0
|
160
|
+
move_on_after_with_optional_reset(interval, with_value, &block)
|
161
|
+
else
|
162
|
+
Polyphony.backend_timeout(interval, nil, with_value, &block)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns the first message from the current fiber's mailbox. If the mailbox
|
167
|
+
# is empty, blocks until a message is available.
|
168
|
+
#
|
169
|
+
# @return [any] received message
|
170
|
+
def receive
|
171
|
+
Fiber.current.receive
|
172
|
+
end
|
173
|
+
|
174
|
+
# Returns all messages currently pending on the current fiber's mailbox.
|
175
|
+
#
|
176
|
+
# @return [Array] array of received messages
|
177
|
+
def receive_all_pending
|
178
|
+
Fiber.current.receive_all_pending
|
179
|
+
end
|
180
|
+
|
181
|
+
# Supervises the current fiber's children. See `Fiber#supervise` for
|
182
|
+
# options.
|
183
|
+
#
|
184
|
+
# @param args [Array] positional parameters
|
185
|
+
# @param opts [Hash] named parameters
|
186
|
+
# @return [any]
|
187
|
+
def supervise(*args, **opts, &block)
|
188
|
+
Fiber.current.supervise(*args, **opts, &block)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Sleeps for the given duration. If the duration is `nil`, sleeps
|
192
|
+
# indefinitely.
|
193
|
+
#
|
194
|
+
# @param duration [Number, nil] duration
|
195
|
+
# @return [any]
|
196
|
+
def sleep(duration = nil)
|
197
|
+
duration ?
|
198
|
+
Polyphony.backend_sleep(duration) : Polyphony.backend_wait_event(true)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Starts a throttled loop with the given rate. If `count:` is given, the
|
202
|
+
# loop is run for the given number of times. Otherwise, the loop is
|
203
|
+
# infinite. The loop rate (times per second) can be given as the rate
|
204
|
+
# parameter. The throttling can also be controlled by providing an
|
205
|
+
# `interval:` or `rate:` named parameter.
|
206
|
+
#
|
207
|
+
# @param rate [Number, nil] loop rate (times per second)
|
208
|
+
# @option opts [Number] :rate loop rate (times per second)
|
209
|
+
# @option opts [Number] :interval loop interval in seconds
|
210
|
+
# @option opts [Number] :count number of iterations (nil for infinite)
|
211
|
+
# @return [any]
|
212
|
+
def throttled_loop(rate = nil, **opts, &block)
|
213
|
+
throttler = Polyphony::Throttler.new(rate || opts)
|
214
|
+
if opts[:count]
|
215
|
+
opts[:count].times { |_i| throttler.(&block) }
|
216
|
+
else
|
217
|
+
while true
|
218
|
+
throttler.(&block)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
rescue LocalJumpError, StopIteration
|
222
|
+
# break called or StopIteration raised
|
223
|
+
end
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
# Helper method for performing a `cancel_after` with optional reset.
|
228
|
+
#
|
229
|
+
# @param interval [Number] timeout interval in seconds
|
230
|
+
# @param exception [Exception, Class, Array<class, message>] exception spec
|
231
|
+
# @return [any] block's return value
|
232
|
+
def cancel_after_with_optional_reset(interval, exception, &block)
|
233
|
+
fiber = Fiber.current
|
234
|
+
canceller = spin do
|
235
|
+
Polyphony.backend_sleep(interval)
|
236
|
+
exception = cancel_exception(exception)
|
237
|
+
exception.raising_fiber = Fiber.current
|
238
|
+
fiber.cancel(exception)
|
239
|
+
end
|
240
|
+
block.call(canceller)
|
241
|
+
ensure
|
242
|
+
canceller.stop
|
243
|
+
end
|
244
|
+
|
245
|
+
# Converts the given exception spec to an exception instance.
|
246
|
+
#
|
247
|
+
# @param exception [Exception, Class, Array<class, message>] exception spec
|
248
|
+
# @return [Exception] exception instance
|
249
|
+
def cancel_exception(exception)
|
250
|
+
case exception
|
251
|
+
when Class then exception.new
|
252
|
+
when Array then exception[0].new(exception[1])
|
253
|
+
else RuntimeError.new(exception)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Helper method for performing `#spin_loop` without throttling. Spins up a
|
258
|
+
# new fiber in which to run the loop.
|
259
|
+
#
|
260
|
+
# @param tag [any] new fiber's tag
|
261
|
+
# @param caller [Array<String>] caller info
|
262
|
+
# @param block [Proc] code to run
|
263
|
+
# @return [any]
|
264
|
+
def spin_loop_without_throttling(tag, caller, block)
|
265
|
+
Fiber.current.spin(tag, caller) do
|
266
|
+
block.call while true
|
267
|
+
rescue LocalJumpError, StopIteration
|
268
|
+
# break called or StopIteration raised
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Helper method for performing `#move_on_after` with optional reset.
|
273
|
+
#
|
274
|
+
# @param interval [Number] timeout interval in seconds
|
275
|
+
# @param value [any] return value in case of timeout
|
276
|
+
# @return [any] return value of given block or timeout value
|
277
|
+
def move_on_after_with_optional_reset(interval, value, &block)
|
278
|
+
fiber = Fiber.current
|
279
|
+
canceller = spin do
|
280
|
+
sleep interval
|
281
|
+
fiber.move_on(value)
|
282
|
+
end
|
283
|
+
block.call(canceller)
|
284
|
+
rescue Polyphony::MoveOn => e
|
285
|
+
e.value
|
286
|
+
ensure
|
287
|
+
canceller.stop
|
288
|
+
end
|
8
289
|
end
|
@@ -17,7 +17,6 @@ class ::OpenSSL::SSL::SSLSocket
|
|
17
17
|
#
|
18
18
|
# @param socket [TCPSocket] socket to wrap
|
19
19
|
# @param context [OpenSSL::SSL::SSLContext] optional SSL context
|
20
|
-
# @return [void]
|
21
20
|
def initialize(socket, context = nil)
|
22
21
|
socket = socket.respond_to?(:io) ? socket.io || socket : socket
|
23
22
|
context ? orig_initialize(socket, context) : orig_initialize(socket)
|
@@ -155,7 +154,7 @@ class ::OpenSSL::SSL::SSLSocket
|
|
155
154
|
#
|
156
155
|
# @param maxlen [Integer] maximum bytes to receive
|
157
156
|
# @yield [String] read data
|
158
|
-
# @return [
|
157
|
+
# @return [OpenSSL::SSL::SSLSocket] self
|
159
158
|
def read_loop(maxlen = 8192)
|
160
159
|
while (data = sysread(maxlen))
|
161
160
|
yield data
|
@@ -263,8 +262,9 @@ class ::OpenSSL::SSL::SSLServer
|
|
263
262
|
|
264
263
|
# Accepts incoming connections in an infinite loop.
|
265
264
|
#
|
265
|
+
# @param ignore_errors [boolean] whether to ignore IO and SSL errors
|
266
266
|
# @yield [OpenSSL::SSL::SSLSocket] accepted socket
|
267
|
-
# @return [
|
267
|
+
# @return [OpenSSL::SSL::SSLServer] self
|
268
268
|
def accept_loop(ignore_errors = true)
|
269
269
|
loop do
|
270
270
|
yield accept
|
@@ -178,7 +178,7 @@ class Polyphony::Pipe
|
|
178
178
|
#
|
179
179
|
# @param maxlen [Integer] maximum bytes to read
|
180
180
|
# @yield [String] read data
|
181
|
-
# @return [
|
181
|
+
# @return [Polyphony::Pipe] self
|
182
182
|
def read_loop(maxlen = 8192, &block)
|
183
183
|
Polyphony.backend_read_loop(self, maxlen, &block)
|
184
184
|
end
|
@@ -199,7 +199,7 @@ class Polyphony::Pipe
|
|
199
199
|
#
|
200
200
|
# @param receiver [any] receiver object
|
201
201
|
# @param method [Symbol] method to call
|
202
|
-
# @return [
|
202
|
+
# @return [Polyphony::Pipe] self
|
203
203
|
def feed_loop(receiver, method = :call, &block)
|
204
204
|
Polyphony.backend_feed_loop(self, receiver, method, &block)
|
205
205
|
end
|
@@ -37,7 +37,7 @@ class ::Socket < ::BasicSocket
|
|
37
37
|
# Accepts incoming connections in an infinite loop.
|
38
38
|
#
|
39
39
|
# @yield [Socket] accepted socket
|
40
|
-
# @return [
|
40
|
+
# @return [nil]
|
41
41
|
def accept_loop(&block)
|
42
42
|
Polyphony.backend_accept_loop(self, TCPSocket, &block)
|
43
43
|
end
|
@@ -109,7 +109,7 @@ class ::Socket < ::BasicSocket
|
|
109
109
|
#
|
110
110
|
# @param maxlen [Integer] maximum bytes to receive
|
111
111
|
# @yield [String] received data
|
112
|
-
# @return [
|
112
|
+
# @return [Socket] self
|
113
113
|
def recv_loop(maxlen = 8192, &block)
|
114
114
|
Polyphony.backend_recv_loop(self, maxlen, &block)
|
115
115
|
end
|
@@ -131,7 +131,7 @@ class ::Socket < ::BasicSocket
|
|
131
131
|
#
|
132
132
|
# @param receiver [any] receiver object
|
133
133
|
# @param method [Symbol] method to call
|
134
|
-
# @return [
|
134
|
+
# @return [Socket] self
|
135
135
|
def feed_loop(receiver, method = :call, &block)
|
136
136
|
Polyphony.backend_recv_feed_loop(self, receiver, method, &block)
|
137
137
|
end
|
@@ -376,7 +376,7 @@ class ::TCPSocket < ::IPSocket
|
|
376
376
|
#
|
377
377
|
# @param maxlen [Integer] maximum bytes to receive
|
378
378
|
# @yield [String] received data
|
379
|
-
# @return [
|
379
|
+
# @return [Socket] self
|
380
380
|
def recv_loop(maxlen = 8192, &block)
|
381
381
|
Polyphony.backend_recv_loop(self, maxlen, &block)
|
382
382
|
end
|
@@ -398,7 +398,7 @@ class ::TCPSocket < ::IPSocket
|
|
398
398
|
#
|
399
399
|
# @param receiver [any] receiver object
|
400
400
|
# @param method [Symbol] method to call
|
401
|
-
# @return [
|
401
|
+
# @return [Socket] self
|
402
402
|
def feed_loop(receiver, method = :call, &block)
|
403
403
|
Polyphony.backend_recv_feed_loop(self, receiver, method, &block)
|
404
404
|
end
|
@@ -494,7 +494,7 @@ class ::TCPServer < ::TCPSocket
|
|
494
494
|
# Accepts incoming connections in an infinite loop.
|
495
495
|
#
|
496
496
|
# @yield [TCPSocket] accepted socket
|
497
|
-
# @return [
|
497
|
+
# @return [nil]
|
498
498
|
def accept_loop(&block)
|
499
499
|
Polyphony.backend_accept_loop(@io, TCPSocket, &block)
|
500
500
|
end
|
@@ -526,7 +526,7 @@ class ::UNIXServer < ::UNIXSocket
|
|
526
526
|
# Accepts incoming connections in an infinite loop.
|
527
527
|
#
|
528
528
|
# @yield [UNIXSocket] accepted socket
|
529
|
-
# @return [
|
529
|
+
# @return [nil]
|
530
530
|
def accept_loop(&block)
|
531
531
|
Polyphony.backend_accept_loop(self, UNIXSocket, &block)
|
532
532
|
end
|
@@ -588,7 +588,7 @@ class ::UNIXSocket < ::BasicSocket
|
|
588
588
|
#
|
589
589
|
# @param maxlen [Integer] maximum bytes to receive
|
590
590
|
# @yield [String] received data
|
591
|
-
# @return [
|
591
|
+
# @return [Socket] self
|
592
592
|
def recv_loop(maxlen = 8192, &block)
|
593
593
|
Polyphony.backend_recv_loop(self, maxlen, &block)
|
594
594
|
end
|
@@ -610,7 +610,7 @@ class ::UNIXSocket < ::BasicSocket
|
|
610
610
|
#
|
611
611
|
# @param receiver [any] receiver object
|
612
612
|
# @param method [Symbol] method to call
|
613
|
-
# @return [
|
613
|
+
# @return [Socket] self
|
614
614
|
def feed_loop(receiver, method = :call, &block)
|
615
615
|
Polyphony.backend_recv_feed_loop(self, receiver, method, &block)
|
616
616
|
end
|
@@ -12,7 +12,6 @@ class ::Thread
|
|
12
12
|
|
13
13
|
# Initializes the thread.
|
14
14
|
# @param args [Array] arguments to pass to thread block
|
15
|
-
# @return [void]
|
16
15
|
def initialize(*args, &block)
|
17
16
|
@join_wait_queue = []
|
18
17
|
@finalization_mutex = Mutex.new
|
@@ -23,11 +22,12 @@ class ::Thread
|
|
23
22
|
|
24
23
|
# Sets up the thread and its main fiber.
|
25
24
|
#
|
26
|
-
# @return [
|
25
|
+
# @return [Thread] self
|
27
26
|
def setup
|
28
27
|
@main_fiber = Fiber.current
|
29
28
|
@main_fiber.setup_main_fiber
|
30
29
|
setup_fiber_scheduling
|
30
|
+
self
|
31
31
|
end
|
32
32
|
|
33
33
|
# @!visibility private
|
@@ -133,7 +133,7 @@ class ::Thread
|
|
133
133
|
|
134
134
|
# Runs the thread's block, handling any uncaught exceptions.
|
135
135
|
#
|
136
|
-
# @return [
|
136
|
+
# @return [any] thread result value
|
137
137
|
def execute
|
138
138
|
# backend must be created in the context of the new thread, therefore it
|
139
139
|
# cannot be created in Thread#initialize
|
@@ -159,7 +159,6 @@ class ::Thread
|
|
159
159
|
# Finalizes the thread.
|
160
160
|
#
|
161
161
|
# @param result [any] thread's return value
|
162
|
-
# @return [void]
|
163
162
|
def finalize(result)
|
164
163
|
unless Fiber.current.children.empty?
|
165
164
|
Fiber.current.shutdown_all_children
|
@@ -175,7 +174,6 @@ class ::Thread
|
|
175
174
|
# Signals all fibers waiting for the thread to terminate.
|
176
175
|
#
|
177
176
|
# @param result [any] thread's return value
|
178
|
-
# @return [void]
|
179
177
|
def signal_waiters(result)
|
180
178
|
@join_wait_queue.each { |w| w.signal(result) }
|
181
179
|
end
|
data/lib/polyphony/net.rb
CHANGED
@@ -57,7 +57,6 @@ module Polyphony
|
|
57
57
|
#
|
58
58
|
# @param context [SSLContext] SSL context
|
59
59
|
# @param protocols [Array] array of supported protocols
|
60
|
-
# @return [void]
|
61
60
|
def setup_alpn(context, protocols)
|
62
61
|
context.alpn_protocols = protocols
|
63
62
|
context.alpn_select_cb = lambda do |peer_protocols|
|
data/lib/polyphony/version.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
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -144,9 +144,6 @@ files:
|
|
144
144
|
- README.md
|
145
145
|
- Rakefile
|
146
146
|
- TODO.md
|
147
|
-
- assets/echo-fibers.svg
|
148
|
-
- assets/polyphony-logo.png
|
149
|
-
- assets/sleeping-fiber.svg
|
150
147
|
- bin/pdbg
|
151
148
|
- bin/polyphony-debug
|
152
149
|
- bin/stress.rb
|
@@ -154,15 +151,15 @@ files:
|
|
154
151
|
- docs/_user-guide/all-about-timers.md
|
155
152
|
- docs/_user-guide/index.md
|
156
153
|
- docs/_user-guide/web-server.md
|
154
|
+
- docs/assets/echo-fibers.svg
|
155
|
+
- docs/assets/polyphony-logo.png
|
156
|
+
- docs/assets/sleeping-fiber.svg
|
157
157
|
- docs/concurrency.md
|
158
158
|
- docs/design-principles.md
|
159
159
|
- docs/exception-handling.md
|
160
160
|
- docs/extending.md
|
161
161
|
- docs/faq.md
|
162
162
|
- docs/fiber-scheduling.md
|
163
|
-
- docs/index.md
|
164
|
-
- docs/link_rewriter.rb
|
165
|
-
- docs/main-concepts/index.md
|
166
163
|
- docs/overview.md
|
167
164
|
- docs/readme.md
|
168
165
|
- docs/tutorial.md
|
@@ -335,7 +332,6 @@ files:
|
|
335
332
|
- lib/polyphony/core/channel.rb
|
336
333
|
- lib/polyphony/core/debug.rb
|
337
334
|
- lib/polyphony/core/exceptions.rb
|
338
|
-
- lib/polyphony/core/global_api.rb
|
339
335
|
- lib/polyphony/core/resource_pool.rb
|
340
336
|
- lib/polyphony/core/sync.rb
|
341
337
|
- lib/polyphony/core/thread_pool.rb
|
data/docs/index.md
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
---
|
2
|
-
layout: page
|
3
|
-
title: Home
|
4
|
-
nav_order: 1
|
5
|
-
permalink: /
|
6
|
-
next_title: Installing Polyphony
|
7
|
-
---
|
8
|
-
|
9
|
-
<p align="center"><img src="{{ 'polyphony-logo.png' | absolute_url }}" /></p>
|
10
|
-
|
11
|
-
# Polyphony
|
12
|
-
{:.text-center .logo-title}
|
13
|
-
|
14
|
-
## Fine-grained concurrency for Ruby
|
15
|
-
{:.text-center .logo-title}
|
16
|
-
|
17
|
-
Polyphony is a library for building concurrent applications in Ruby. Polyphony
|
18
|
-
implements a comprehensive
|
19
|
-
[fiber](https://ruby-doc.org/core-2.5.1/Fiber.html)-based concurrency model,
|
20
|
-
using [libev](https://github.com/enki/libev) as a high-performance event reactor
|
21
|
-
for I/O, timers, and other asynchronous events.
|
22
|
-
|
23
|
-
[Overview](getting-started/overview){: .btn .btn-green .text-gamma }
|
24
|
-
[Take the tutorial](getting-started/tutorial){: .btn .btn-blue .text-gamma }
|
25
|
-
[Source code](https://github.com/digital-fabric/polyphony){: .btn .btn-purple .text-gamma target="_blank" }
|
26
|
-
{:.text-center .mt-6 .h-align-center }
|
27
|
-
|
28
|
-
## Focused on Developer Happiness
|
29
|
-
|
30
|
-
Polyphony is designed to make concurrent Ruby programming feel natural and
|
31
|
-
fluent. The Polyphony API is easy to use, easy to understand, and above all
|
32
|
-
idiomatic.
|
33
|
-
|
34
|
-
## Optimized for High Performance
|
35
|
-
|
36
|
-
Polyphony offers high performance for I/O bound Ruby apps. Distributing
|
37
|
-
concurrent operations over fibers, instead of threads or processes, minimizes
|
38
|
-
memory consumption and reduces the cost of context-switching.
|
39
|
-
|
40
|
-
## Designed for Interoperability
|
41
|
-
|
42
|
-
With Polyphony you can use any of the stock Ruby classes and modules like `IO`,
|
43
|
-
`Process`, `Socket` and `OpenSSL` in a concurrent multi-fiber environment. In
|
44
|
-
addition, Polyphony provides a structured model for exception handling that
|
45
|
-
builds on and enhances Ruby's exception handling system.
|
46
|
-
|
47
|
-
## A Growing Ecosystem
|
48
|
-
|
49
|
-
Polyphony includes a full-blown HTTP server implementation with integrated
|
50
|
-
support for HTTP 2, WebSockets, TLS/SSL termination and more. Polyphony also
|
51
|
-
provides fiber-aware adapters for connecting to PostgreSQL and Redis. More
|
52
|
-
adapters are being developed.
|
53
|
-
|
54
|
-
## Features
|
55
|
-
|
56
|
-
* Co-operative scheduling of concurrent tasks using Ruby fibers.
|
57
|
-
* High-performance event reactor for handling I/O events and timers.
|
58
|
-
* Natural, sequential programming style that makes it easy to reason about
|
59
|
-
concurrent code.
|
60
|
-
* Abstractions and constructs for controlling the execution of concurrent code:
|
61
|
-
supervisors, throttling, resource pools etc.
|
62
|
-
* Code can use native networking classes and libraries, growing support for
|
63
|
-
third-party gems such as `pg` and `redis`.
|
64
|
-
* Use stdlib classes such as `TCPServer` and `TCPSocket` and `Net::HTTP`.
|
65
|
-
* Competitive performance and scalability characteristics, in terms of both
|
66
|
-
throughput and memory consumption.
|
67
|
-
|
68
|
-
## Prior Art
|
69
|
-
|
70
|
-
Polyphony draws inspiration from the following, in no particular order:
|
71
|
-
|
72
|
-
* [nio4r](https://github.com/socketry/nio4r/) and
|
73
|
-
[async](https://github.com/socketry/async) (Polyphony's C-extension code
|
74
|
-
started as a spinoff of
|
75
|
-
[nio4r's](https://github.com/socketry/nio4r/tree/master/ext))
|
76
|
-
* The [go scheduler](https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html)
|
77
|
-
* [EventMachine](https://github.com/eventmachine/eventmachine)
|
78
|
-
* [Trio](https://trio.readthedocs.io/)
|
79
|
-
* [Erlang supervisors](http://erlang.org/doc/man/supervisor.html) (and actually,
|
80
|
-
Erlang in general)
|
81
|
-
|
82
|
-
## Developer Resources
|
83
|
-
|
84
|
-
* [Tutorial](getting-started/tutorial)
|
85
|
-
* [Main Concepts](main-concepts/concurrency/)
|
86
|
-
* [User Guide](user-guide/all-about-timers/)
|
87
|
-
* [API Reference](api-reference/exception/)
|
88
|
-
* [Examples](https://github.com/digital-fabric/polyphony/tree/9e0f3b09213156bdf376ef33684ef267517f06e8/examples/README.md)
|
89
|
-
|
90
|
-
## Contributing to Polyphony
|
91
|
-
|
92
|
-
Issues and pull requests will be gladly accepted. Please use the [Polyphony git
|
93
|
-
repository](https://github.com/digital-fabric/polyphony) as your primary point
|
94
|
-
of departure for contributing.
|
data/docs/link_rewriter.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'yard'
|
2
|
-
|
3
|
-
# shamelessly copied from https://github.com/troessner/reek/blob/master/docs/yard_plugin.rb
|
4
|
-
|
5
|
-
# Template helper to modify processing of links in HTML generated from our
|
6
|
-
# markdown files.
|
7
|
-
module LocalLinkHelper
|
8
|
-
# Rewrites links to (assumed local) markdown files so they're processed as
|
9
|
-
# {file: } directives.
|
10
|
-
def resolve_links(text)
|
11
|
-
text = text.gsub(%r{<a href="(docs/[^"]*.md)">([^<]*)</a>}, '{file:/\1 \2}')
|
12
|
-
.gsub(%r{<img src="(assets/[^"]*)">}, '{rdoc-image:/\1}')
|
13
|
-
super text
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
YARD::Templates::Template.extra_includes << LocalLinkHelper
|