polyphony 0.99 → 0.99.1

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.
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
- ```