polyphony 0.43.8
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 +7 -0
- data/.gitbook.yaml +4 -0
- data/.github/workflows/test.yml +29 -0
- data/.gitignore +59 -0
- data/.rubocop.yml +175 -0
- data/CHANGELOG.md +393 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +141 -0
- data/LICENSE +21 -0
- data/README.md +51 -0
- data/Rakefile +26 -0
- data/TODO.md +201 -0
- data/bin/polyphony-debug +87 -0
- data/docs/_config.yml +64 -0
- data/docs/_includes/head.html +40 -0
- data/docs/_includes/title.html +1 -0
- data/docs/_sass/custom/custom.scss +10 -0
- data/docs/_sass/overrides.scss +0 -0
- data/docs/_user-guide/all-about-timers.md +126 -0
- data/docs/_user-guide/index.md +9 -0
- data/docs/_user-guide/web-server.md +136 -0
- data/docs/api-reference/exception.md +27 -0
- data/docs/api-reference/fiber.md +425 -0
- data/docs/api-reference/index.md +9 -0
- data/docs/api-reference/io.md +36 -0
- data/docs/api-reference/object.md +99 -0
- data/docs/api-reference/polyphony-baseexception.md +33 -0
- data/docs/api-reference/polyphony-cancel.md +26 -0
- data/docs/api-reference/polyphony-moveon.md +24 -0
- data/docs/api-reference/polyphony-net.md +20 -0
- data/docs/api-reference/polyphony-process.md +28 -0
- data/docs/api-reference/polyphony-resourcepool.md +59 -0
- data/docs/api-reference/polyphony-restart.md +18 -0
- data/docs/api-reference/polyphony-terminate.md +18 -0
- data/docs/api-reference/polyphony-threadpool.md +67 -0
- data/docs/api-reference/polyphony-throttler.md +77 -0
- data/docs/api-reference/polyphony.md +36 -0
- data/docs/api-reference/thread.md +88 -0
- data/docs/assets/img/echo-fibers.svg +1 -0
- data/docs/assets/img/sleeping-fiber.svg +1 -0
- data/docs/faq.md +195 -0
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/index.md +10 -0
- data/docs/getting-started/installing.md +34 -0
- data/docs/getting-started/overview.md +486 -0
- data/docs/getting-started/tutorial.md +359 -0
- data/docs/index.md +94 -0
- data/docs/main-concepts/concurrency.md +151 -0
- data/docs/main-concepts/design-principles.md +161 -0
- data/docs/main-concepts/exception-handling.md +291 -0
- data/docs/main-concepts/extending.md +89 -0
- data/docs/main-concepts/fiber-scheduling.md +197 -0
- data/docs/main-concepts/index.md +9 -0
- data/docs/polyphony-logo.png +0 -0
- data/examples/adapters/concurrent-ruby.rb +9 -0
- data/examples/adapters/pg_client.rb +36 -0
- data/examples/adapters/pg_notify.rb +35 -0
- data/examples/adapters/pg_pool.rb +43 -0
- data/examples/adapters/pg_transaction.rb +31 -0
- data/examples/adapters/redis_blpop.rb +12 -0
- data/examples/adapters/redis_channels.rb +122 -0
- data/examples/adapters/redis_client.rb +19 -0
- data/examples/adapters/redis_pubsub.rb +26 -0
- data/examples/adapters/redis_pubsub_perf.rb +68 -0
- data/examples/core/01-spinning-up-fibers.rb +18 -0
- data/examples/core/02-awaiting-fibers.rb +20 -0
- data/examples/core/03-interrupting.rb +39 -0
- data/examples/core/04-handling-signals.rb +19 -0
- data/examples/core/xx-agent.rb +102 -0
- data/examples/core/xx-at_exit.rb +29 -0
- data/examples/core/xx-caller.rb +12 -0
- data/examples/core/xx-channels.rb +45 -0
- data/examples/core/xx-daemon.rb +14 -0
- data/examples/core/xx-deadlock.rb +8 -0
- data/examples/core/xx-deferring-an-operation.rb +14 -0
- data/examples/core/xx-erlang-style-genserver.rb +81 -0
- data/examples/core/xx-exception-backtrace.rb +40 -0
- data/examples/core/xx-fork-cleanup.rb +22 -0
- data/examples/core/xx-fork-spin.rb +42 -0
- data/examples/core/xx-fork-terminate.rb +27 -0
- data/examples/core/xx-forking.rb +24 -0
- data/examples/core/xx-move_on.rb +23 -0
- data/examples/core/xx-pingpong.rb +18 -0
- data/examples/core/xx-queue-async.rb +120 -0
- data/examples/core/xx-readpartial.rb +18 -0
- data/examples/core/xx-recurrent-timer.rb +12 -0
- data/examples/core/xx-resource_delegate.rb +31 -0
- data/examples/core/xx-signals.rb +16 -0
- data/examples/core/xx-sleep-forever.rb +9 -0
- data/examples/core/xx-sleeping.rb +25 -0
- data/examples/core/xx-snooze-starve.rb +16 -0
- data/examples/core/xx-spin-fork.rb +49 -0
- data/examples/core/xx-spin_error_backtrace.rb +33 -0
- data/examples/core/xx-state-machine.rb +51 -0
- data/examples/core/xx-stop.rb +20 -0
- data/examples/core/xx-supervise-process.rb +30 -0
- data/examples/core/xx-supervisors.rb +21 -0
- data/examples/core/xx-thread-selector-sleep.rb +51 -0
- data/examples/core/xx-thread-selector-snooze.rb +46 -0
- data/examples/core/xx-thread-sleep.rb +17 -0
- data/examples/core/xx-thread-snooze.rb +34 -0
- data/examples/core/xx-thread_pool.rb +17 -0
- data/examples/core/xx-throttling.rb +18 -0
- data/examples/core/xx-timeout.rb +10 -0
- data/examples/core/xx-timer-gc.rb +17 -0
- data/examples/core/xx-trace.rb +79 -0
- data/examples/core/xx-using-a-mutex.rb +21 -0
- data/examples/core/xx-worker-thread.rb +30 -0
- data/examples/io/tunnel.rb +48 -0
- data/examples/io/xx-backticks.rb +11 -0
- data/examples/io/xx-echo_client.rb +25 -0
- data/examples/io/xx-echo_client_from_stdin.rb +21 -0
- data/examples/io/xx-echo_pipe.rb +16 -0
- data/examples/io/xx-echo_server.rb +17 -0
- data/examples/io/xx-echo_server_with_timeout.rb +34 -0
- data/examples/io/xx-echo_stdin.rb +14 -0
- data/examples/io/xx-happy-eyeballs.rb +36 -0
- data/examples/io/xx-httparty.rb +38 -0
- data/examples/io/xx-irb.rb +17 -0
- data/examples/io/xx-net-http.rb +15 -0
- data/examples/io/xx-open.rb +16 -0
- data/examples/io/xx-switch.rb +15 -0
- data/examples/io/xx-system.rb +11 -0
- data/examples/io/xx-tcpserver.rb +15 -0
- data/examples/io/xx-tcpsocket.rb +18 -0
- data/examples/io/xx-zip.rb +19 -0
- data/examples/performance/fiber_transfer.rb +47 -0
- data/examples/performance/fs_read.rb +38 -0
- data/examples/performance/mem-usage.rb +56 -0
- data/examples/performance/messaging.rb +29 -0
- data/examples/performance/multi_snooze.rb +33 -0
- data/examples/performance/snooze.rb +39 -0
- data/examples/performance/snooze_raw.rb +39 -0
- data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +74 -0
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +45 -0
- data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +58 -0
- data/examples/performance/thread-vs-fiber/threaded_server.rb +27 -0
- data/examples/performance/thread-vs-fiber/xx-httparty_multi.rb +36 -0
- data/examples/performance/thread-vs-fiber/xx-httparty_threaded.rb +29 -0
- data/examples/performance/thread_pool_perf.rb +63 -0
- data/examples/performance/xx-array.rb +11 -0
- data/examples/performance/xx-fiber-switch.rb +9 -0
- data/examples/performance/xx-snooze.rb +15 -0
- data/examples/xx-spin.rb +32 -0
- data/ext/libev/Changes +548 -0
- data/ext/libev/LICENSE +37 -0
- data/ext/libev/README +59 -0
- data/ext/libev/README.embed +3 -0
- data/ext/libev/ev.c +5279 -0
- data/ext/libev/ev.h +856 -0
- data/ext/libev/ev_epoll.c +296 -0
- data/ext/libev/ev_kqueue.c +224 -0
- data/ext/libev/ev_linuxaio.c +642 -0
- data/ext/libev/ev_poll.c +156 -0
- data/ext/libev/ev_port.c +192 -0
- data/ext/libev/ev_select.c +316 -0
- data/ext/libev/ev_vars.h +215 -0
- data/ext/libev/ev_win32.c +162 -0
- data/ext/libev/ev_wrap.h +216 -0
- data/ext/libev/test_libev_win32.c +123 -0
- data/ext/polyphony/extconf.rb +20 -0
- data/ext/polyphony/fiber.c +109 -0
- data/ext/polyphony/libev.c +2 -0
- data/ext/polyphony/libev.h +9 -0
- data/ext/polyphony/libev_agent.c +882 -0
- data/ext/polyphony/polyphony.c +71 -0
- data/ext/polyphony/polyphony.h +97 -0
- data/ext/polyphony/polyphony_ext.c +21 -0
- data/ext/polyphony/queue.c +168 -0
- data/ext/polyphony/ring_buffer.c +96 -0
- data/ext/polyphony/ring_buffer.h +28 -0
- data/ext/polyphony/thread.c +208 -0
- data/ext/polyphony/tracing.c +11 -0
- data/lib/polyphony.rb +136 -0
- data/lib/polyphony/adapters/fs.rb +19 -0
- data/lib/polyphony/adapters/irb.rb +52 -0
- data/lib/polyphony/adapters/postgres.rb +110 -0
- data/lib/polyphony/adapters/process.rb +33 -0
- data/lib/polyphony/adapters/redis.rb +67 -0
- data/lib/polyphony/adapters/trace.rb +138 -0
- data/lib/polyphony/core/channel.rb +46 -0
- data/lib/polyphony/core/exceptions.rb +36 -0
- data/lib/polyphony/core/global_api.rb +124 -0
- data/lib/polyphony/core/resource_pool.rb +117 -0
- data/lib/polyphony/core/sync.rb +21 -0
- data/lib/polyphony/core/thread_pool.rb +64 -0
- data/lib/polyphony/core/throttler.rb +41 -0
- data/lib/polyphony/event.rb +17 -0
- data/lib/polyphony/extensions/core.rb +174 -0
- data/lib/polyphony/extensions/fiber.rb +379 -0
- data/lib/polyphony/extensions/io.rb +221 -0
- data/lib/polyphony/extensions/openssl.rb +81 -0
- data/lib/polyphony/extensions/socket.rb +150 -0
- data/lib/polyphony/extensions/thread.rb +108 -0
- data/lib/polyphony/net.rb +77 -0
- data/lib/polyphony/version.rb +5 -0
- data/polyphony.gemspec +40 -0
- data/test/coverage.rb +54 -0
- data/test/eg.rb +27 -0
- data/test/helper.rb +56 -0
- data/test/q.rb +24 -0
- data/test/run.rb +5 -0
- data/test/stress.rb +25 -0
- data/test/test_agent.rb +130 -0
- data/test/test_event.rb +59 -0
- data/test/test_ext.rb +196 -0
- data/test/test_fiber.rb +988 -0
- data/test/test_global_api.rb +352 -0
- data/test/test_io.rb +249 -0
- data/test/test_kernel.rb +57 -0
- data/test/test_process_supervision.rb +46 -0
- data/test/test_queue.rb +112 -0
- data/test/test_resource_pool.rb +138 -0
- data/test/test_signal.rb +100 -0
- data/test/test_socket.rb +34 -0
- data/test/test_supervise.rb +103 -0
- data/test/test_thread.rb +170 -0
- data/test/test_thread_pool.rb +101 -0
- data/test/test_throttler.rb +50 -0
- data/test/test_trace.rb +68 -0
- metadata +482 -0
@@ -0,0 +1,36 @@
|
|
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.
|
@@ -0,0 +1,99 @@
|
|
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_pending → [*object]
|
67
|
+
|
68
|
+
Shortcut for `Fiber.current.receive_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
|
+
```
|
@@ -0,0 +1,33 @@
|
|
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
|
+
```
|
@@ -0,0 +1,26 @@
|
|
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
|
+
```
|
@@ -0,0 +1,24 @@
|
|
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
|
+
```
|
@@ -0,0 +1,20 @@
|
|
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.
|
@@ -0,0 +1,28 @@
|
|
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
|
+
```
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: Polyphony::ResourcePool
|
4
|
+
parent: API Reference
|
5
|
+
permalink: /api-reference/polyphony-resourcepool/
|
6
|
+
---
|
7
|
+
# Polyphony::ResourcePool
|
8
|
+
|
9
|
+
`Polyphony::ResourcePool` implements a general purpose resource pool for
|
10
|
+
limiting concurrent access to a resource or multiple copies thereof. A resource
|
11
|
+
pool might be used for example to limit the number of concurrent database
|
12
|
+
connections.
|
13
|
+
|
14
|
+
## Class methods
|
15
|
+
|
16
|
+
## Instance methods
|
17
|
+
|
18
|
+
### #acquire({ block })
|
19
|
+
|
20
|
+
Acquires a resource and passes it to the given block. The resource will be used
|
21
|
+
exclusively by the given block, and then returned to the pool. This method
|
22
|
+
blocks until the given block has completed running. If no resource is available,
|
23
|
+
this method blocks until a resource has been released.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
db_connections = Polyphony::ResourcePool.new(limit: 5) { PG.connect(opts) }
|
27
|
+
|
28
|
+
def query_records(sql)
|
29
|
+
db_connections.acquire do |db|
|
30
|
+
db.query(sql).to_a
|
31
|
+
end
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
### #available → count
|
36
|
+
|
37
|
+
Returns the number of resources currently available in the resource pool.
|
38
|
+
|
39
|
+
### #initialize(limit: number, { block })
|
40
|
+
|
41
|
+
Initializes a new resource pool with the given maximum number of concurrent
|
42
|
+
resources. The given block is used to create the resource.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
require 'postgres'
|
46
|
+
|
47
|
+
opts = { host: '/tmp', user: 'admin', dbname: 'mydb' }
|
48
|
+
db_connections = Polyphony::ResourcePool.new(limit: 5) { PG.connect(opts) }
|
49
|
+
```
|
50
|
+
|
51
|
+
### #limit → count
|
52
|
+
|
53
|
+
Returns the size limit of the resource pool.
|
54
|
+
|
55
|
+
### #size → count
|
56
|
+
|
57
|
+
Returns the total number of allocated resources in the resource pool. This
|
58
|
+
includes both available and unavailable resources.
|
59
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: Polyphony::Restart
|
4
|
+
parent: API Reference
|
5
|
+
permalink: /api-reference/polyphony-restart/
|
6
|
+
---
|
7
|
+
# Polyphony::Restart
|
8
|
+
|
9
|
+
`Polyphony::Restart` is an exception class used to restart a fiber. Applications
|
10
|
+
will not normally raise a `Polyphony::Restart` exception, but would rather use
|
11
|
+
`Fiber#restart`.
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
f = spin { do_something_slow }
|
15
|
+
...
|
16
|
+
f.restart
|
17
|
+
...
|
18
|
+
```
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: Polyphony::Terminate
|
4
|
+
parent: API Reference
|
5
|
+
permalink: /api-reference/polyphony-terminate/
|
6
|
+
---
|
7
|
+
# Polyphony::Terminate
|
8
|
+
|
9
|
+
`Polyphony::Terminate` is an exception class used to terminate a fiber without
|
10
|
+
propagating the exception. It should never be rescued. A `Polyphony::Terminate`
|
11
|
+
exception is normally raised using APIs such as `Fiber#terminate` or
|
12
|
+
`Fiber#terminate_all_children`.
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
f = spin { do_something_slow }
|
16
|
+
...
|
17
|
+
f.terminate
|
18
|
+
```
|
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: Polyphony::ThreadPool
|
4
|
+
parent: API Reference
|
5
|
+
permalink: /api-reference/polyphony-threadpool/
|
6
|
+
---
|
7
|
+
# Polyphony::ThreadPool
|
8
|
+
|
9
|
+
`Polyphony::ThreadPool` implements a general purpose thread pool, normally used
|
10
|
+
for the execution of non-fiber aware operations, such as C-extension based
|
11
|
+
third-party libraries or other system call blocking APIs. The Polyphony
|
12
|
+
implementation of a thread pool allows limiting the number of threads used for
|
13
|
+
performing a recurring operation across one or more fibers.
|
14
|
+
|
15
|
+
A default thread pool is available for quick access to this feature.
|
16
|
+
|
17
|
+
## Class methods
|
18
|
+
|
19
|
+
### #process({ block }) → object
|
20
|
+
|
21
|
+
Runs the given block on the default thread pool. The default pool will be
|
22
|
+
created on the first call to `#process`. This method will block until the
|
23
|
+
operation has completed. The return value is that of the given block. Any
|
24
|
+
uncaught exception will be propagated to the callsite.
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
result = Polyphony::ThreadPool.process { lengthy_op }
|
28
|
+
```
|
29
|
+
|
30
|
+
## Instance methods
|
31
|
+
|
32
|
+
### #busy? → true or false
|
33
|
+
|
34
|
+
Returns true if operations are currently being run on the thread pool.
|
35
|
+
|
36
|
+
### cast({ block }) → pool
|
37
|
+
|
38
|
+
Runs the given block on one of the threads in the pool in a fire-and-forget
|
39
|
+
manner, without waiting for the operation to complete. Using `#cast` to run an
|
40
|
+
operation means there's no way of knowing if the operation has completed or if
|
41
|
+
any exception has been raised, other than inside the block.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
my_pool.cast { puts 'Hello world' }
|
45
|
+
do_something_else
|
46
|
+
```
|
47
|
+
|
48
|
+
### #initialize(size = Etc.nprocessors)
|
49
|
+
|
50
|
+
Initializes a new instance of `Polyphony::ThreadPool` with the given maximum
|
51
|
+
number of threads. The default size is the number of available processors
|
52
|
+
(number of CPU cores).
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
my_pool = Polyphony::ThreadPool.new(3)
|
56
|
+
```
|
57
|
+
|
58
|
+
### #process({ block }) → object
|
59
|
+
|
60
|
+
Runs the given block on one of the threads in the thread pool and blocks until
|
61
|
+
the operation has completed. The return value is that of the given block. Any
|
62
|
+
uncaught exception will be propagated to the callsite.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
pool = Polyphony::ThreadPool.new(3)
|
66
|
+
result = pool.process { lengthy_op }
|
67
|
+
```
|