polyphony 0.99.4 → 0.99.6
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 +11 -0
- data/.yardopts +0 -2
- data/README.md +1 -1
- data/docs/readme.md +1 -1
- data/docs/tutorial.md +2 -2
- data/examples/pipes/gzip_http_server.rb +2 -2
- data/examples/pipes/http_server.rb +1 -1
- data/examples/pipes/tcp_proxy.rb +1 -1
- data/ext/polyphony/backend_common.c +4 -4
- data/ext/polyphony/backend_io_uring.c +8 -8
- data/ext/polyphony/backend_libev.c +5 -5
- data/ext/polyphony/fiber.c +33 -42
- data/ext/polyphony/io_extensions.c +50 -37
- data/ext/polyphony/pipe.c +6 -20
- data/ext/polyphony/polyphony.c +72 -144
- data/ext/polyphony/queue.c +23 -63
- data/ext/polyphony/thread.c +4 -13
- data/lib/polyphony/adapters/process.rb +2 -5
- data/lib/polyphony/adapters/sequel.rb +2 -2
- data/lib/polyphony/core/debug.rb +1 -4
- data/lib/polyphony/core/exceptions.rb +1 -5
- data/lib/polyphony/core/resource_pool.rb +7 -8
- data/lib/polyphony/core/sync.rb +5 -8
- data/lib/polyphony/core/thread_pool.rb +3 -10
- data/lib/polyphony/core/throttler.rb +1 -5
- data/lib/polyphony/core/timer.rb +23 -30
- data/lib/polyphony/extensions/fiber.rb +513 -543
- data/lib/polyphony/extensions/io.rb +5 -14
- data/lib/polyphony/extensions/object.rb +283 -2
- data/lib/polyphony/extensions/openssl.rb +5 -26
- data/lib/polyphony/extensions/pipe.rb +6 -17
- data/lib/polyphony/extensions/socket.rb +24 -118
- data/lib/polyphony/extensions/thread.rb +3 -18
- data/lib/polyphony/extensions/timeout.rb +0 -1
- data/lib/polyphony/net.rb +5 -9
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +2 -6
- data/test/test_io.rb +221 -221
- data/test/test_socket.rb +3 -3
- data/test/test_trace.rb +2 -2
- 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 -309
- /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
@@ -108,7 +108,7 @@ class ::IO
|
|
108
108
|
def double_splice(src, dest)
|
109
109
|
Polyphony.backend_double_splice(src, dest)
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
# Tees data from the source to the desination.
|
113
113
|
#
|
114
114
|
# @param src [IO, Polyphony::Pipe] source to tee from
|
@@ -232,7 +232,7 @@ class ::IO
|
|
232
232
|
Polyphony.backend_write(self, str)
|
233
233
|
self
|
234
234
|
end
|
235
|
-
|
235
|
+
|
236
236
|
# @!visibility private
|
237
237
|
alias_method :orig_gets, :gets
|
238
238
|
|
@@ -350,24 +350,16 @@ class ::IO
|
|
350
350
|
buf ? readpartial(maxlen, buf) : readpartial(maxlen)
|
351
351
|
end
|
352
352
|
|
353
|
-
# call-seq:
|
354
|
-
# io.read_loop { |data| ... }
|
355
|
-
# io.read_loop(maxlen) { |data| ... }
|
356
|
-
#
|
357
353
|
# Reads up to `maxlen` bytes at a time in an infinite loop. Read data
|
358
354
|
# will be passed to the given block.
|
359
355
|
#
|
360
356
|
# @param maxlen [Integer] maximum bytes to receive
|
361
|
-
# @yield [String]
|
362
|
-
# @return [
|
357
|
+
# @yield [String] read data
|
358
|
+
# @return [IO] self
|
363
359
|
def read_loop(maxlen = 8192, &block)
|
364
360
|
Polyphony.backend_read_loop(self, maxlen, &block)
|
365
361
|
end
|
366
362
|
|
367
|
-
# call-seq:
|
368
|
-
# io.feed_loop(receiver, method)
|
369
|
-
# io.feed_loop(receiver, method) { |result| ... }
|
370
|
-
#
|
371
363
|
# Receives data from the io in an infinite loop, passing the data to the given
|
372
364
|
# receiver using the given method. If a block is given, the result of the
|
373
365
|
# method call to the receiver is passed to the block.
|
@@ -384,8 +376,7 @@ class ::IO
|
|
384
376
|
#
|
385
377
|
# @param receiver [any] receiver object
|
386
378
|
# @param method [Symbol] method to call
|
387
|
-
# @
|
388
|
-
# @return [void]
|
379
|
+
# @return [IO] self
|
389
380
|
def feed_loop(receiver, method = :call, &block)
|
390
381
|
Polyphony.backend_feed_loop(self, receiver, method, &block)
|
391
382
|
end
|
@@ -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)
|
@@ -89,12 +88,6 @@ class ::OpenSSL::SSL::SSLSocket
|
|
89
88
|
# @!visibility private
|
90
89
|
alias_method :orig_read, :read
|
91
90
|
|
92
|
-
# call-seq:
|
93
|
-
# socket.read -> string
|
94
|
-
# socket.read(maxlen) -> string
|
95
|
-
# socket.read(maxlen, buf) -> buf
|
96
|
-
# socket.read(maxlen, buf, buf_pos) -> buf
|
97
|
-
#
|
98
91
|
# Reads from the socket. If `maxlen` is given, reads up to `maxlen` bytes from
|
99
92
|
# the socket, otherwise reads to `EOF`. If `buf` is given, it is used as the
|
100
93
|
# buffer to read into, otherwise a new string is allocated. If `buf_pos` is
|
@@ -123,12 +116,6 @@ class ::OpenSSL::SSL::SSLSocket
|
|
123
116
|
buf
|
124
117
|
end
|
125
118
|
|
126
|
-
# call-seq:
|
127
|
-
# socket.readpartial(maxlen) -> string
|
128
|
-
# socket.readpartial(maxlen, buf) -> buf
|
129
|
-
# socket.readpartial(maxlen, buf, buf_pos) -> buf
|
130
|
-
# socket.readpartial(maxlen, buf, buf_pos, raise_on_eof) -> buf
|
131
|
-
#
|
132
119
|
# Reads up to `maxlen` from the socket. If `buf` is given, it is used as the
|
133
120
|
# buffer to read into, otherwise a new string is allocated. If `buf_pos` is
|
134
121
|
# given, reads into the given offset (in bytes) in the given buffer. If the
|
@@ -162,18 +149,12 @@ class ::OpenSSL::SSL::SSLSocket
|
|
162
149
|
result
|
163
150
|
end
|
164
151
|
|
165
|
-
# call-seq:
|
166
|
-
# socket.recv_loop { |data| ... }
|
167
|
-
# socket.recv_loop(maxlen) { |data| ... }
|
168
|
-
# socket.read_loop { |data| ... }
|
169
|
-
# socket.read_loop(maxlen) { |data| ... }
|
170
|
-
#
|
171
152
|
# Receives up to `maxlen` bytes at a time in an infinite loop. Read buffers
|
172
153
|
# will be passed to the given block.
|
173
154
|
#
|
174
155
|
# @param maxlen [Integer] maximum bytes to receive
|
175
|
-
# @yield [String]
|
176
|
-
# @return [
|
156
|
+
# @yield [String] read data
|
157
|
+
# @return [OpenSSL::SSL::SSLSocket] self
|
177
158
|
def read_loop(maxlen = 8192)
|
178
159
|
while (data = sysread(maxlen))
|
179
160
|
yield data
|
@@ -279,13 +260,11 @@ class ::OpenSSL::SSL::SSLServer
|
|
279
260
|
orig_close
|
280
261
|
end
|
281
262
|
|
282
|
-
# call-seq:
|
283
|
-
# socket.accept_loop { |conn| ... }
|
284
|
-
#
|
285
263
|
# Accepts incoming connections in an infinite loop.
|
286
264
|
#
|
287
|
-
# @
|
288
|
-
# @
|
265
|
+
# @param ignore_errors [boolean] whether to ignore IO and SSL errors
|
266
|
+
# @yield [OpenSSL::SSL::SSLSocket] accepted socket
|
267
|
+
# @return [OpenSSL::SSL::SSLServer] self
|
289
268
|
def accept_loop(ignore_errors = true)
|
290
269
|
loop do
|
291
270
|
yield accept
|
@@ -72,7 +72,7 @@ class Polyphony::Pipe
|
|
72
72
|
end
|
73
73
|
|
74
74
|
# Writes to the pipe.
|
75
|
-
|
75
|
+
|
76
76
|
# @param buf [String] data to write
|
77
77
|
# @param args [any] further arguments to pass to Polyphony.backend_write
|
78
78
|
# @return [Integer] bytes written
|
@@ -81,7 +81,7 @@ class Polyphony::Pipe
|
|
81
81
|
end
|
82
82
|
|
83
83
|
# Writes to the pipe.
|
84
|
-
|
84
|
+
|
85
85
|
# @param buf [String] data to write
|
86
86
|
# @return [Integer] bytes written
|
87
87
|
def <<(buf)
|
@@ -89,12 +89,6 @@ class Polyphony::Pipe
|
|
89
89
|
self
|
90
90
|
end
|
91
91
|
|
92
|
-
# call-seq:
|
93
|
-
# pipe.gets(limit, chomp)
|
94
|
-
# pipe.gets(separator, limit, chomp)
|
95
|
-
#
|
96
|
-
# Reads a single line from the pipe.
|
97
|
-
#
|
98
92
|
# @param sep [String] line separator
|
99
93
|
# @param _limit [Integer, nil] line length limit
|
100
94
|
# @param _chomp [boolean, nil] whether to chomp the read line
|
@@ -134,7 +128,7 @@ class Polyphony::Pipe
|
|
134
128
|
LINEFEED_RE = /\n$/.freeze
|
135
129
|
|
136
130
|
# Writes a line with line feed to the pipe.
|
137
|
-
#
|
131
|
+
#
|
138
132
|
# @param args [Array] zero or more lines
|
139
133
|
def puts(*args)
|
140
134
|
if args.empty?
|
@@ -183,16 +177,12 @@ class Polyphony::Pipe
|
|
183
177
|
# Runs a read loop.
|
184
178
|
#
|
185
179
|
# @param maxlen [Integer] maximum bytes to read
|
186
|
-
# @yield [String] read
|
187
|
-
# @return [
|
180
|
+
# @yield [String] read data
|
181
|
+
# @return [Polyphony::Pipe] self
|
188
182
|
def read_loop(maxlen = 8192, &block)
|
189
183
|
Polyphony.backend_read_loop(self, maxlen, &block)
|
190
184
|
end
|
191
185
|
|
192
|
-
# call-seq:
|
193
|
-
# pipe.feed_loop(receiver, method)
|
194
|
-
# pipe.feed_loop(receiver, method) { |result| ... }
|
195
|
-
#
|
196
186
|
# Receives data from the pipe in an infinite loop, passing the data to the
|
197
187
|
# given receiver using the given method. If a block is given, the result of
|
198
188
|
# the method call to the receiver is passed to the block.
|
@@ -209,8 +199,7 @@ class Polyphony::Pipe
|
|
209
199
|
#
|
210
200
|
# @param receiver [any] receiver object
|
211
201
|
# @param method [Symbol] method to call
|
212
|
-
# @
|
213
|
-
# @return [void]
|
202
|
+
# @return [Polyphony::Pipe] self
|
214
203
|
def feed_loop(receiver, method = :call, &block)
|
215
204
|
Polyphony.backend_feed_loop(self, receiver, method, &block)
|
216
205
|
end
|