polyphony 0.99 → 0.99.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -1
  3. data/.rubocop.yml +3 -3
  4. data/.yardopts +30 -0
  5. data/CHANGELOG.md +4 -0
  6. data/LICENSE +1 -1
  7. data/README.md +63 -29
  8. data/Rakefile +1 -5
  9. data/TODO.md +0 -4
  10. data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
  11. data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
  12. data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
  13. data/docs/{main-concepts/extending.md → extending.md} +2 -9
  14. data/docs/faq.md +3 -16
  15. data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
  16. data/docs/link_rewriter.rb +16 -0
  17. data/docs/{getting-started/overview.md → overview.md} +1 -30
  18. data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
  19. data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
  20. data/examples/adapters/redis_client.rb +3 -2
  21. data/examples/io/echo_server.rb +1 -1
  22. data/examples/io/echo_server_plain_ruby.rb +26 -0
  23. data/ext/polyphony/backend_io_uring.c +154 -9
  24. data/ext/polyphony/backend_io_uring_context.c +21 -12
  25. data/ext/polyphony/backend_io_uring_context.h +12 -7
  26. data/ext/polyphony/backend_libev.c +1 -1
  27. data/ext/polyphony/extconf.rb +24 -8
  28. data/ext/polyphony/fiber.c +79 -2
  29. data/ext/polyphony/io_extensions.c +53 -0
  30. data/ext/polyphony/pipe.c +42 -2
  31. data/ext/polyphony/polyphony.c +345 -31
  32. data/ext/polyphony/polyphony.h +9 -2
  33. data/ext/polyphony/queue.c +181 -0
  34. data/ext/polyphony/ring_buffer.c +0 -1
  35. data/ext/polyphony/runqueue.c +8 -1
  36. data/ext/polyphony/runqueue_ring_buffer.c +13 -0
  37. data/ext/polyphony/runqueue_ring_buffer.h +2 -1
  38. data/ext/polyphony/socket_extensions.c +6 -0
  39. data/ext/polyphony/thread.c +34 -2
  40. data/lib/polyphony/adapters/process.rb +11 -1
  41. data/lib/polyphony/adapters/sequel.rb +1 -1
  42. data/lib/polyphony/core/channel.rb +2 -0
  43. data/lib/polyphony/core/debug.rb +1 -1
  44. data/lib/polyphony/core/global_api.rb +25 -24
  45. data/lib/polyphony/core/resource_pool.rb +7 -6
  46. data/lib/polyphony/core/sync.rb +2 -2
  47. data/lib/polyphony/core/thread_pool.rb +3 -3
  48. data/lib/polyphony/core/timer.rb +8 -8
  49. data/lib/polyphony/extensions/exception.rb +2 -0
  50. data/lib/polyphony/extensions/fiber.rb +15 -13
  51. data/lib/polyphony/extensions/io.rb +127 -5
  52. data/lib/polyphony/extensions/kernel.rb +20 -2
  53. data/lib/polyphony/extensions/openssl.rb +100 -11
  54. data/lib/polyphony/extensions/pipe.rb +103 -7
  55. data/lib/polyphony/extensions/process.rb +13 -1
  56. data/lib/polyphony/extensions/socket.rb +93 -27
  57. data/lib/polyphony/extensions/thread.rb +9 -1
  58. data/lib/polyphony/extensions/timeout.rb +1 -1
  59. data/lib/polyphony/version.rb +2 -1
  60. data/lib/polyphony.rb +27 -7
  61. data/polyphony.gemspec +1 -8
  62. data/test/stress.rb +1 -1
  63. data/test/test_global_api.rb +45 -7
  64. data/test/test_socket.rb +96 -0
  65. data/test/test_timer.rb +5 -5
  66. metadata +17 -40
  67. data/docs/_config.yml +0 -64
  68. data/docs/_includes/head.html +0 -40
  69. data/docs/_includes/title.html +0 -1
  70. data/docs/_sass/custom/custom.scss +0 -10
  71. data/docs/_sass/overrides.scss +0 -0
  72. data/docs/api-reference/exception.md +0 -31
  73. data/docs/api-reference/fiber.md +0 -425
  74. data/docs/api-reference/index.md +0 -9
  75. data/docs/api-reference/io.md +0 -36
  76. data/docs/api-reference/object.md +0 -99
  77. data/docs/api-reference/polyphony-baseexception.md +0 -33
  78. data/docs/api-reference/polyphony-cancel.md +0 -26
  79. data/docs/api-reference/polyphony-moveon.md +0 -24
  80. data/docs/api-reference/polyphony-net.md +0 -20
  81. data/docs/api-reference/polyphony-process.md +0 -28
  82. data/docs/api-reference/polyphony-resourcepool.md +0 -59
  83. data/docs/api-reference/polyphony-restart.md +0 -18
  84. data/docs/api-reference/polyphony-terminate.md +0 -18
  85. data/docs/api-reference/polyphony-threadpool.md +0 -67
  86. data/docs/api-reference/polyphony-throttler.md +0 -77
  87. data/docs/api-reference/polyphony.md +0 -36
  88. data/docs/api-reference/thread.md +0 -88
  89. data/docs/favicon.ico +0 -0
  90. data/docs/getting-started/index.md +0 -10
  91. data/docs/getting-started/installing.md +0 -34
  92. /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
  93. /data/{docs → assets}/polyphony-logo.png +0 -0
  94. /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
@@ -1,425 +0,0 @@
1
- ---
2
- layout: page
3
- title: ::Fiber
4
- parent: API Reference
5
- permalink: /api-reference/fiber/
6
- # prev_title: Tutorial
7
- # next_title: How Fibers are Scheduled
8
- ---
9
- # ::Fiber
10
-
11
- [Ruby core Fiber documentation](https://ruby-doc.org/core-2.7.0/Fiber.html)
12
-
13
- Polyphony enhances the core `Fiber` class with APIs for scheduling, exception
14
- handling, message passing, and more. Normally, fibers should be created using
15
- `Object#spin` or `Fiber#spin`, but some fibers might be created implicitly when
16
- using lazy enumerators or third party gems. For fibers created implicitly,
17
- Polyphony provides `Fiber#setup_raw`, which enables scheduling and message
18
- passing for such fibers.
19
-
20
- While most work on fibers since their introduction into MRI Ruby has
21
- concentrated on `Fiber#resume` and `Fiber.yield` for transferring control
22
- between fibers, Polyphony uses `Fiber#transfer` exclusively, which allows
23
- fully symmetric transfer of control between fibers.
24
-
25
- ## Class Methods
26
-
27
- ### ::await(\*fibers) → [\*result]
28
-
29
- Awaits all given fibers, returning when all fibers have terminated. If one of
30
- the given fibers terminates with an uncaught exception, `::await` will terminate
31
- and await all fibers that are still running, then reraise the exception. All the
32
- given fibers are guaranteed to have terminated when `::await` returns. If no
33
- exception is raised, `::await` returns an array containing the results of all
34
- given fibers, in the same order.
35
-
36
- ```ruby
37
- f1 = spin { sleep 1 }
38
- f2 = spin { sleep 2 }
39
- Fiber.await(f1, f2)
40
- ```
41
-
42
- ### ::select(\*fibers) → [\*result]
43
-
44
- Selects the first fiber to have terminated among the given fibers. If any of the
45
- given fibers terminates with an uncaught exception, `::select` will reraise the
46
- exception. If no exception is raised, `::select` returns an array containing the
47
- fiber and its result. All given fibers are guaranteed to have terminated when
48
- `::select` returns.
49
-
50
- ```ruby
51
- # get the fastest reply of a bunch of URLs
52
- fibers = urls.map { |u| spin { [u, HTTParty.get(u)] } }
53
- fiber, (url, result) = Fiber.select(*fibers)
54
- ```
55
-
56
- ## Instance methods
57
-
58
- ### #&lt;&lt;(object) → fiber<br>#send(object) → fiber
59
-
60
- Adds a message to the fiber's mailbox. The message can be any object. This
61
- method is complemented by `Fiber#receive`.
62
-
63
- ```ruby
64
- f = spin do
65
- loop do
66
- receiver, x = receive
67
- receiver << x * 10
68
- end
69
- end
70
- f << 2
71
- result = receive #=> 20
72
- ```
73
-
74
- ### #auto_watcher → async
75
-
76
- Returns a reusable `Gyro::Async` watcher instance associated with the fiber.
77
- This method provides a way to minimize watcher allocation. Instead of allocating
78
- a new async watcher every time one is needed, the same watcher associated with
79
- the fiber is reused.
80
-
81
- ```ruby
82
- def work(async)
83
- do_something
84
- async.signal
85
- end
86
-
87
- async = Fiber.current.auto_watcher
88
- spin { work(async) }
89
- async.await
90
- ```
91
-
92
- ### #await → object<br>#join → object
93
-
94
- Awaits the termination of the fiber. If the fiber terminates with an uncaught
95
- exception, `#await` will reraise the exception. Otherwise `#await` returns the
96
- result of the fiber.
97
-
98
- ```ruby
99
- f = spin { 'foo' }
100
- f.await #=> 'foo'
101
- ```
102
-
103
- ### #await_all_children → fiber
104
-
105
- Waits for all the fiber's child fibers to terminate. This method is normally
106
- coupled with `Fiber#terminate_all_children`. See also
107
- `Fiber#shutdown_all_children`.
108
-
109
- ```ruby
110
- jobs.each { |j| spin { process(j) } }
111
- sleep 1
112
- terminate_all_children
113
- await_all_children
114
- ```
115
-
116
- ### #caller → [*location]
117
-
118
- Return the execution stack of the fiber, including that of the fiber from which
119
- it was spun.
120
-
121
- ```ruby
122
- spin {
123
- spin {
124
- spin {
125
- pp Fiber.current.caller
126
- }.await
127
- }.await
128
- }.await
129
-
130
- #=> ["examples/core/xx-caller.rb:3:in `block (2 levels) in <main>'",
131
- #=> "examples/core/xx-caller.rb:2:in `block in <main>'",
132
- #=> "examples/core/xx-caller.rb:1:in `<main>'"]
133
- ```
134
-
135
- ### #cancel! → fiber
136
-
137
- Terminates the fiber by raising a `Polyphony::Cancel` exception. If uncaught,
138
- the exception will be propagated.
139
-
140
- ```ruby
141
- f = spin { sleep 1 }
142
- f.cancel! #=> exception: Polyphony::Cancel
143
- ```
144
-
145
- ### #children → [\*fiber]
146
-
147
- Returns an array containing all of the fiber's child fibers. A child fiber's
148
- lifetime is limited to that of its immediate parent.
149
-
150
- ```ruby
151
- f1 = spin { sleep 1 }
152
- f2 = spin { sleep 1 }
153
- f3 = spin { sleep 1 }
154
- Fiber.current.children #=> [f1, f2, f3]
155
- ```
156
-
157
- ### #interrupt(object = nil) → fiber<br>#stop(object = nil) → fiber
158
-
159
- Terminates the fiber by raising a `Polyphony::MoveOn` exception in its context.
160
- The given object will be set as the fiber's result. Note that a `MoveOn`
161
- exception is never propagated.
162
-
163
- ```ruby
164
- f = spin { do_something_slow }
165
- f.interrupt('never mind')
166
- f.await #=> 'never mind'
167
- ```
168
-
169
- ### #location → string
170
-
171
- Returns the location of the fiber's associated block, or `(root)` for the main
172
- fiber.
173
-
174
- ### #main? → true or false
175
-
176
- Returns true if the fiber is the main fiber for its thread.
177
-
178
- ### #parent → fiber
179
-
180
- Returns the fiber's parent fiber. The main fiber's parent is nil.
181
-
182
- ```ruby
183
- f = spin { sleep 1 }
184
- f.parent #=> Fiber.current
185
- ```
186
-
187
- ### #raise(\*args) → fiber
188
-
189
- Raises an error in the context of the fiber. The given exception can be a string
190
- (for raising `RuntimeError` exceptions with a given message), an exception
191
- class, or an exception instance. If no argument is given, a `RuntimeError` will
192
- be raised. Uncaught exceptions will be propagated.
193
-
194
- ```ruby
195
- f = spin { sleep 1 }
196
- f.raise('foo') # raises a RuntimeError
197
- f.raise(MyException, 'my error message') # exception class with message
198
- f.raise(MyException.new('my error message')) # exception instance
199
- # or simply
200
- f.raise
201
- ```
202
-
203
- ### #receive → object
204
-
205
- Pops the first message from the fiber's mailbox. If no message is available,
206
- `#receive` will block until a message is pushed to the mailbox. The received
207
- message can be any kind of object. This method is complemented by
208
- `Fiber#<<`/`Fiber#send`.
209
-
210
- ```ruby
211
- spin { Fiber.current.parent << 'hello from child' }
212
- message = receive #=> 'hello from child'
213
- ```
214
-
215
- ### #receive_all_pending → [*object]
216
-
217
- Returns all messages currently in the mailbox, emptying the mailbox. This method
218
- does not block if no the mailbox is already empty. This method may be used to
219
- process any pending messages upon fiber termination:
220
-
221
- ```ruby
222
- worker = spin do
223
- loop do
224
- job = receive
225
- handle_job(job)
226
- end
227
- rescue Polyphony::Terminate => e
228
- receive_all_pending.each { |job| handle_job(job) }
229
- end
230
- ```
231
-
232
- ### #restart(object = nil) → fiber<br>#reset(object = nil) → fiber
233
-
234
- Restarts the fiber, essentially rerunning the fiber's associated block,
235
- restoring it to its primary state. If the fiber is already terminated, a new
236
- fiber will be created and returned. If the fiber's block takes an argument, its
237
- value can be set by passing it to `#restart`.
238
-
239
- ```ruby
240
- counter = 0
241
- f = spin { sleep 1; counter += 1 }
242
- f.await #=> 1
243
- f.restart
244
- f.await #=> 2
245
- ```
246
-
247
- ### #result → object
248
-
249
- Returns the result of the fiber. If the fiber has not yet terminated, `nil` is
250
- returned. If the fiber terminated with an uncaught exception, the exception is
251
- returned.
252
-
253
- ```ruby
254
- f = spin { sleep 1; 'foo' }
255
- f.await
256
- f.result #=> 'foo'
257
- ```
258
-
259
- ### #running? → true or false
260
-
261
- Returns true if the fiber is not yet terminated.
262
-
263
- ### #schedule(object = nil) → fiber
264
-
265
- Adds the fiber to its thread's run queue. The fiber will be eventually resumed
266
- with the given value, which can be any object. If an exception is given, it will
267
- be raised in the context of the fiber upon resuming. If the fiber is already on
268
- the run queue, the resume value will be updated.
269
-
270
- ```ruby
271
- f = spin do
272
- result = suspend
273
- p result
274
- end
275
-
276
- sleep 0.1
277
- f.schedule 'foo'
278
- f.await
279
- #=> 'foo'
280
- ```
281
-
282
- ### #shutdown_all_children → fiber
283
-
284
- Terminates all of the fiber's child fibers and blocks until all are terminated.
285
- This method is can be used to replace calls to `#terminate_all_children`
286
- followed by `#await_all_children`.
287
-
288
- ```ruby
289
- jobs.each { |j| spin { process(j) } }
290
- sleep 1
291
- shutdown_all_children
292
- ```
293
-
294
- ### #spin(tag = nil, { block }) → fiber
295
-
296
- Creates a new fiber with self as its parent. The returned fiber is put on the
297
- run queue of the parent fiber's associated thread. A tag of any object type can
298
- be associated with the fiber. Note that `Object#spin` is a shortcut for
299
- `Fiber.current.spin`.
300
-
301
- ```ruby
302
- f = Fiber.current.spin { |x|'foo' }
303
- f.await #=> 'foo'
304
- ```
305
-
306
- If the block takes an argument, its value can be controlled by explicitly
307
- calling `Fiber#schedule`. The result of the given block (the value of the last
308
- statement in the block) can be retrieved using `Fiber#result` or by otherwise
309
- using fiber control APIs such as `Fiber#await`.
310
-
311
- ```ruby
312
- f = spin { |x| x * 10 }
313
- f.schedule(2)
314
- f.await #=> 20
315
- ```
316
-
317
- ### #state → symbol
318
-
319
- Returns the fiber's current state, which can be any of the following:
320
-
321
- - `:waiting` - the fiber is currently waiting for an operation to complete.
322
- - `:runnable` - the fiber is scheduled to be resumed (put on the run queue).
323
- - `:running` - the fiber is currently running.
324
- - `:dead` - the fiber has terminated.
325
-
326
- ### #supervise(opts = {}) → fiber
327
-
328
- Supervises all child fibers, optionally restarting any fiber that terminates.
329
-
330
- The given `opts` argument controls the behaviour of the supervision. The
331
- following options are currently supported:
332
-
333
- - `:restart`: restart options
334
- - `nil` - Child fibers are not restarted (default behaviour).
335
- - `true` - Any child fiber that terminates is restarted.
336
- - `:on_error` - Any child fiber that terminates with an uncaught exception is
337
- restarted.
338
- - `:watcher`: a fiber watching supervision events.
339
-
340
- If a watcher fiber is specified, it will receive supervision events to its
341
- mailbox. The events are of the form `[<event_type>, <fiber>]`, for example
342
- `[:restart, child_fiber_1]`. Here's an example of using a watcher fiber:
343
-
344
- ```ruby
345
- watcher = spin_loop do
346
- kind, fiber = receive
347
- case kind
348
- when :restart
349
- puts "fiber #{fiber.inspect} restarted"
350
- end
351
- end
352
- ...
353
- supervise(restart: true, watcher: watcher)
354
- ```
355
-
356
- ### #tag → object
357
-
358
- Returns the tag associated with the fiber, normally passed to `Fiber#spin`. The
359
- tag can be any kind of object. The default tag is `nil`.
360
-
361
- ```ruby
362
- f = spin(:worker) { do_some_work }
363
- f.tag #=> :worker
364
- ```
365
-
366
- ### #tag=(object) → object
367
-
368
- Sets the tag associated with the fiber. The tag can be any kind of object.
369
-
370
- ```ruby
371
- f = spin { do_some_work }
372
- f.tag = :worker
373
- ```
374
-
375
- ### #terminate → fiber
376
-
377
- Terminates the fiber by raising a `Polyphony::Terminate` exception. The
378
- exception is not propagated. Note that the fiber is not guaranteed to terminate
379
- before `#terminate` returns. The fiber will need to run first in order to raise
380
- the `Terminate` exception and terminate. This method is normally coupled with
381
- `Fiber#await`:
382
-
383
- ```ruby
384
- f1 = spin { sleep 1 }
385
- f2 = spin { sleep 2 }
386
-
387
- f1.await
388
-
389
- f2.terminate
390
- f2.await
391
- ```
392
-
393
- ### #terminate_all_children → fiber
394
-
395
- Terminates all of the fiber's child fibers. Note that `#terminate_all_children`
396
- does not acutally wait for all child fibers to terminate. This method is
397
- normally coupled with `Fiber#await_all_children`. See also `Fiber#shutdown_all_children`.
398
-
399
- ```ruby
400
- jobs.each { |j| spin { process(j) } }
401
- sleep 1
402
- terminate_all_children
403
- await_all_children
404
- ```
405
-
406
- ### #thread → thread
407
-
408
- Returns the thread to which the fiber belongs.
409
-
410
- ```ruby
411
- f = spin(:worker) { do_some_work }
412
- f.thread #=> Thread.current
413
- ```
414
-
415
- ### #when_done({ block }) → fiber
416
-
417
- Installs a hook to be called when the fiber is terminated. The block will be
418
- called with the fiber's result. If the fiber terminates with an uncaught
419
- exception, the exception will be passed to the block.
420
-
421
- ```ruby
422
- f = spin { 'foo' }
423
- f.when_done { |r| puts "got #{r} from fiber" }
424
- f.await #=> STDOUT: 'got foo from fiber'
425
- ```
@@ -1,9 +0,0 @@
1
- ---
2
- layout: page
3
- title: API Reference
4
- has_children: true
5
- nav_order: 5
6
- ---
7
-
8
- # API Reference
9
- {: .no_toc }
@@ -1,36 +0,0 @@
1
- ---
2
- layout: page
3
- title: ::IO
4
- parent: API Reference
5
- permalink: /api-reference/io/
6
- ---
7
- # ::IO
8
-
9
- [Ruby core IO documentation](https://ruby-doc.org/core-2.7.0/IO.html)
10
-
11
- Polyphony reimplements a significant number of IO class and instance methods to
12
- be fiber-aware. Polyphony also adds methods for accessing the associated event
13
- watchers.
14
-
15
- ## Class Methods
16
-
17
- ## Instance methods
18
-
19
- ### #read_watcher → io_watcher
20
-
21
- Returns the read watcher associated with the IO. The watcher is automatically
22
- created and cached. The watcher is an instance of `Gyro::IO`. Normally this
23
- method is not called directly from application code.
24
-
25
- ```ruby
26
- def read_ten_chars(io)
27
- io.read_watcher.await
28
- io.read(10)
29
- end
30
- ```
31
-
32
- ### #write_watcher → io_watcher
33
-
34
- Returns the write watcher associated with the IO. The watcher is automatically
35
- created and cached. The watcher is an instance of `Gyro::IO`. Normally this
36
- method is not called directly from application code.
@@ -1,99 +0,0 @@
1
- ---
2
- layout: page
3
- title: ::Object (Global API)
4
- parent: API Reference
5
- permalink: /api-reference/object/
6
- ---
7
- # ::Object (Global API)
8
-
9
- The global Polyphony API is designed to feel almost like a part of the Ruby
10
- runtime. The global API contains multiple methods for creating and controlling
11
- fibers, as well as miscellaneous methods for dealing with timers and other
12
- events, with minimal boilerplate. The API is implemented as a module included in
13
- the `Object` class, allowing access from any receiver.
14
-
15
- ### #after(interval, { block }) → fiber
16
-
17
- Run the given block after the given time interval (specified in seconds). This
18
- method spins up a separate fiber that will sleep for the given interval, then
19
- run the given block.
20
-
21
- ```ruby
22
- f = spin { do_some_big_work }
23
- after(1) { f.stop }
24
- f.await
25
- ```
26
-
27
- ### #cancel_after(interval, { block }) → object
28
-
29
- Run the given block, cancelling it after the given time interval by raising a
30
- `Polyphony::Cancel` exception. If uncaught, the exception will be propagated.
31
-
32
- ```ruby
33
- spin do
34
- cancel_after(3) { do_some_work }
35
- rescue Polyphony::Cancel
36
- puts "work was cancelled"
37
- end
38
- ```
39
-
40
- ### #every(interval, { block }) → object
41
-
42
- Runs the given block repeatedly, at the given time interval. This method will
43
- block until an exception is raised.
44
-
45
- ```ruby
46
- every(3) do
47
- puts "I'm still alive"
48
- end
49
- ```
50
-
51
- ### #move_on_after(interval, with_value: nil, { block }) → object
52
-
53
- Run the given block, interrupting it after the given time interval by raising a
54
- `Polyphony::MoveOn` exception. The `with_value` keyword argument can be used to
55
- set the value returned from the block if the timeout has elapsed.
56
-
57
- ```ruby
58
- result = move_on_after(3, with_value: 'bar') { sleep 5; 'foo' }
59
- result #=> 'bar'
60
- ```
61
-
62
- ### #receive → object
63
-
64
- Shortcut for `Fiber.current.receive`
65
-
66
- ### #receive_all_pending → [*object]
67
-
68
- Shortcut for `Fiber.current.receive_all_pending`
69
-
70
- ### #sleep(duration = nil) → fiber
71
-
72
- Sleeps for the given duration.
73
-
74
- ### #spin(tag = nil, { block}) → fiber
75
-
76
- Shortcut for `Fiber.current.spin`
77
-
78
- ### #spin_loop(tag = nil, rate: nil, &block) → fiber
79
-
80
- Spins up a new fiber that runs the given block in a loop. If `rate` is given,
81
- the loop is throttled to run `rate` times per second.
82
-
83
- ```ruby
84
- # print twice a second
85
- f = spin_loop(rate: 2) { puts 'hello world' }
86
- sleep 2
87
- f.stop
88
- ```
89
-
90
- ### #throttled_loop(rate, count: nil, &block) → object
91
-
92
- Runs the given block in a loop at the given rate (times per second). If `count`
93
- is given, the loop will be run for the specified number of times and then
94
- returns. Otherwise, the loop is infinite (unless an exception is raised).
95
-
96
- ```ruby
97
- # twice a second
98
- throttled_loop(2) { puts 'hello world' }
99
- ```
@@ -1,33 +0,0 @@
1
- ---
2
- layout: page
3
- title: Polyphony::BaseException
4
- parent: API Reference
5
- permalink: /api-reference/polyphony-baseexception/
6
- ---
7
- # Polyphony::BaseException
8
-
9
- The `Polyphony::BaseException` is a common base class for exceptions used to
10
- control fiber execution. Instances of descendant classes are meant to be created
11
- explicitly using `new`, e.g. `Polyphony::MoveOn.new`, rather than using `raise
12
- Polyphony::MoveOn`. Normally an application will not use those classes directly
13
- but would rather use APIs such as `Fiber#interrupt`.
14
-
15
- ## Derived classes
16
-
17
- - [`Polyphony::Cancel`](../polyphony-cancel/)
18
- - [`Polyphony::MoveOn`](../polyphony-moveon/)
19
- - [`Polyphony::Restart`](../polyphony-restart/)
20
- - [`Polyphony::Terminate`](../polyphony-terminate/)
21
-
22
- ## Instance methods
23
-
24
- ### #initialize(value = nil)
25
-
26
- Initializes the exception with an optional result value. The value will be used
27
- as the result of the block being interrupted or the fiber being terminated.
28
-
29
- ```ruby
30
- f = spin { 'foo' }
31
- f.raise(Polyphony::Terminate.new('bar'))
32
- f.await #=> 'bar'
33
- ```
@@ -1,26 +0,0 @@
1
- ---
2
- layout: page
3
- title: Polyphony::Cancel
4
- parent: API Reference
5
- permalink: /api-reference/polyphony-cancel/
6
- ---
7
- # Polyphony::Cancel
8
-
9
- `Polyphony::Cancel` is an exception class used to interrupt a blocking operation
10
- with an exception that must be rescued. This exception is will propagate if not
11
- rescued. A `Polyphony::Cancel` exception is normally raised using APIs such as
12
- `Fiber#cancel!` or `Object#cancel_after`.
13
-
14
- ```ruby
15
- require 'httparty'
16
- require 'time'
17
-
18
- def current_server_time
19
- cancel_after(10) do
20
- response_body = HTTParty.get(TIME_URL).body
21
- Time.parse(response_body)
22
- end
23
- rescue Polyphony::Cancel
24
- Time.now
25
- end
26
- ```
@@ -1,24 +0,0 @@
1
- ---
2
- layout: page
3
- title: Polyphony::MoveOn
4
- parent: API Reference
5
- permalink: /api-reference/polyphony-moveon/
6
- ---
7
- # Polyphony::MoveOn
8
-
9
- `Polyphony::MoveOn` is an exception class used to interrupt a blocking operation
10
- without propagating the excception. A `Polyphony::MoveOn` exception is normally
11
- raised using APIs such as `Fiber#interrupt` or `Object#move_on_after`. This
12
- exception allows you to set the result of the operation being interrupted.
13
-
14
- ```ruby
15
-
16
- def do_something_slow
17
- sleep 10
18
- 'foo'
19
- end
20
-
21
- f = spin { do_something_slow }
22
- f.interrupt('bar')
23
- f.await #=> 'bar'
24
- ```
@@ -1,20 +0,0 @@
1
- ---
2
- layout: page
3
- title: Polyphony::Net
4
- parent: API Reference
5
- permalink: /api-reference/polyphony-net/
6
- ---
7
- # Polyphony::Net
8
-
9
- The `Polyphony::Net` provides convenience methods for working with sockets. The
10
- module unifies secure and non-secure socket APIs.
11
-
12
- ## Class Methods
13
-
14
- ### #tcp_connect(host, port, opts = {}) → socket
15
-
16
- Connects to a TCP server.
17
-
18
- ### #tcp_listen(host = nil, port = nil, opts = {}) → socket
19
-
20
- Opens a server socket for listening to incoming connections.
@@ -1,28 +0,0 @@
1
- ---
2
- layout: page
3
- title: Polyphony::Process
4
- parent: API Reference
5
- permalink: /api-reference/polyphony-process/
6
- ---
7
- # Polyphony::Process
8
-
9
- The `Polyphony::Process` module is used to watch child processes.
10
-
11
- ## Class Methods
12
-
13
- ### #watch(cmd = nil, { block })
14
-
15
- Starts a child process, blocking until the child process terminates. If `#watch`
16
- is interrupted before the child process terminates, the child process is sent a
17
- `TERM` signal, and awaited. After 5 seconds, if the child has still not
18
- terminated, it will be sent a `KILL` signal and awaited. This method is normally
19
- used in conjunction with `#supervise` in order to supervise child processes.
20
-
21
- If `cmd` is given, the child process is started using `Kernel#spawn` running a
22
- shell command. If a block is given, the child process is started using
23
- [`Polyphony#fork`](../polyphony/#fork-block---pid).
24
-
25
- ```ruby
26
- spin { Polyphony::Process.watch('echo "Hello World"; sleep 1') }
27
- supervise(restart: :always)
28
- ```