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
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
polyphony (0.43.8)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
addressable (2.7.0)
|
10
|
+
public_suffix (>= 2.0.2, < 5.0)
|
11
|
+
ansi (1.5.0)
|
12
|
+
ast (2.4.0)
|
13
|
+
builder (3.2.4)
|
14
|
+
colorator (1.1.0)
|
15
|
+
concurrent-ruby (1.1.6)
|
16
|
+
docile (1.3.2)
|
17
|
+
em-websocket (0.5.1)
|
18
|
+
eventmachine (>= 0.12.9)
|
19
|
+
http_parser.rb (~> 0.6.0)
|
20
|
+
eventmachine (1.2.7)
|
21
|
+
ffi (1.12.1)
|
22
|
+
forwardable-extended (2.6.0)
|
23
|
+
hiredis (0.6.3)
|
24
|
+
http_parser.rb (0.6.0)
|
25
|
+
httparty (0.17.0)
|
26
|
+
mime-types (~> 3.0)
|
27
|
+
multi_xml (>= 0.5.2)
|
28
|
+
i18n (0.9.5)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
jekyll (3.8.6)
|
31
|
+
addressable (~> 2.4)
|
32
|
+
colorator (~> 1.0)
|
33
|
+
em-websocket (~> 0.5)
|
34
|
+
i18n (~> 0.7)
|
35
|
+
jekyll-sass-converter (~> 1.0)
|
36
|
+
jekyll-watch (~> 2.0)
|
37
|
+
kramdown (~> 1.14)
|
38
|
+
liquid (~> 4.0)
|
39
|
+
mercenary (~> 0.3.3)
|
40
|
+
pathutil (~> 0.9)
|
41
|
+
rouge (>= 1.7, < 4)
|
42
|
+
safe_yaml (~> 1.0)
|
43
|
+
jekyll-remote-theme (0.4.1)
|
44
|
+
addressable (~> 2.0)
|
45
|
+
jekyll (>= 3.5, < 5.0)
|
46
|
+
rubyzip (>= 1.3.0)
|
47
|
+
jekyll-sass-converter (1.5.2)
|
48
|
+
sass (~> 3.4)
|
49
|
+
jekyll-seo-tag (2.6.1)
|
50
|
+
jekyll (>= 3.3, < 5.0)
|
51
|
+
jekyll-watch (2.2.1)
|
52
|
+
listen (~> 3.0)
|
53
|
+
json (2.3.0)
|
54
|
+
just-the-docs (0.3.0)
|
55
|
+
jekyll (>= 3.8.5)
|
56
|
+
jekyll-seo-tag (~> 2.0)
|
57
|
+
rake (>= 12.3.1, < 13.1.0)
|
58
|
+
kramdown (1.17.0)
|
59
|
+
liquid (4.0.3)
|
60
|
+
listen (3.2.1)
|
61
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
62
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
63
|
+
localhost (1.1.4)
|
64
|
+
mercenary (0.3.6)
|
65
|
+
mime-types (3.3.1)
|
66
|
+
mime-types-data (~> 3.2015)
|
67
|
+
mime-types-data (3.2019.1009)
|
68
|
+
minitest (5.13.0)
|
69
|
+
minitest-reporters (1.4.2)
|
70
|
+
ansi
|
71
|
+
builder
|
72
|
+
minitest (>= 5.0)
|
73
|
+
ruby-progressbar
|
74
|
+
multi_xml (0.6.0)
|
75
|
+
parallel (1.19.1)
|
76
|
+
parser (2.7.0.2)
|
77
|
+
ast (~> 2.4.0)
|
78
|
+
pathutil (0.16.2)
|
79
|
+
forwardable-extended (~> 2.6)
|
80
|
+
pg (1.1.4)
|
81
|
+
public_suffix (4.0.3)
|
82
|
+
rainbow (3.0.0)
|
83
|
+
rake (12.3.3)
|
84
|
+
rake-compiler (1.0.5)
|
85
|
+
rake
|
86
|
+
rb-fsevent (0.10.3)
|
87
|
+
rb-inotify (0.10.1)
|
88
|
+
ffi (~> 1.0)
|
89
|
+
redis (4.1.0)
|
90
|
+
regexp_parser (1.7.1)
|
91
|
+
rexml (3.2.4)
|
92
|
+
rouge (3.15.0)
|
93
|
+
rubocop (0.85.1)
|
94
|
+
parallel (~> 1.10)
|
95
|
+
parser (>= 2.7.0.1)
|
96
|
+
rainbow (>= 2.2.2, < 4.0)
|
97
|
+
regexp_parser (>= 1.7)
|
98
|
+
rexml
|
99
|
+
rubocop-ast (>= 0.0.3)
|
100
|
+
ruby-progressbar (~> 1.7)
|
101
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
102
|
+
rubocop-ast (0.0.3)
|
103
|
+
parser (>= 2.7.0.1)
|
104
|
+
ruby-progressbar (1.10.1)
|
105
|
+
rubyzip (2.0.0)
|
106
|
+
safe_yaml (1.0.5)
|
107
|
+
sass (3.7.4)
|
108
|
+
sass-listen (~> 4.0.0)
|
109
|
+
sass-listen (4.0.0)
|
110
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
111
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
112
|
+
simplecov (0.17.1)
|
113
|
+
docile (~> 1.1)
|
114
|
+
json (>= 1.8, < 3)
|
115
|
+
simplecov-html (~> 0.10.0)
|
116
|
+
simplecov-html (0.10.2)
|
117
|
+
unicode-display_width (1.6.1)
|
118
|
+
|
119
|
+
PLATFORMS
|
120
|
+
ruby
|
121
|
+
|
122
|
+
DEPENDENCIES
|
123
|
+
hiredis (= 0.6.3)
|
124
|
+
http_parser.rb (~> 0.6.0)
|
125
|
+
httparty (= 0.17.0)
|
126
|
+
jekyll (~> 3.8.6)
|
127
|
+
jekyll-remote-theme (~> 0.4.1)
|
128
|
+
jekyll-seo-tag (~> 2.6.1)
|
129
|
+
just-the-docs (~> 0.3.0)
|
130
|
+
localhost (= 1.1.4)
|
131
|
+
minitest (= 5.13.0)
|
132
|
+
minitest-reporters (= 1.4.2)
|
133
|
+
pg (= 1.1.4)
|
134
|
+
polyphony!
|
135
|
+
rake-compiler (= 1.0.5)
|
136
|
+
redis (= 4.1.0)
|
137
|
+
rubocop (= 0.85.1)
|
138
|
+
simplecov (= 0.17.1)
|
139
|
+
|
140
|
+
BUNDLED WITH
|
141
|
+
2.1.4
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Sharon Rosner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
<p align="center"><img src="docs/polyphony-logo.png" /></p>
|
2
|
+
|
3
|
+
# Polyphony - Fine-Grained Concurrency for Ruby
|
4
|
+
|
5
|
+
[](http://rubygems.org/gems/polyphony)
|
6
|
+
[](https://github.com/digital-fabric/polyphony/actions?query=workflow%3ATests)
|
7
|
+
[](https://github.com/digital-fabric/polyphony/blob/master/LICENSE)
|
8
|
+
|
9
|
+
[DOCS](https://digital-fabric.github.io/polyphony/) |
|
10
|
+
[EXAMPLES](examples)
|
11
|
+
|
12
|
+
> Polyphony \| pəˈlɪf\(ə\)ni \|
|
13
|
+
> 1. _Music_ the style of simultaneously combining a number of parts, each
|
14
|
+
> forming an individual melody and harmonizing with each other.
|
15
|
+
> 2. _Programming_ a Ruby gem for concurrent programming focusing on performance
|
16
|
+
> and developer happiness.
|
17
|
+
|
18
|
+
## What is Polyphony
|
19
|
+
|
20
|
+
Polyphony is a library for building concurrent applications in Ruby. Polyphony
|
21
|
+
harnesses the power of [Ruby fibers](https://ruby-doc.org/core-2.5.1/Fiber.html)
|
22
|
+
to provide a cooperative, sequential coroutine-based concurrency model. Under
|
23
|
+
the hood, Polyphony uses [libev](https://github.com/enki/libev) as a
|
24
|
+
high-performance event reactor that provides timers, I/O watchers and other
|
25
|
+
asynchronous event primitives.
|
26
|
+
|
27
|
+
## Features
|
28
|
+
|
29
|
+
* Co-operative scheduling of concurrent tasks using Ruby fibers.
|
30
|
+
* High-performance event reactor for handling I/O events and timers.
|
31
|
+
* Natural, sequential programming style that makes it easy to reason about
|
32
|
+
concurrent code.
|
33
|
+
* Abstractions and constructs for controlling the execution of concurrent code:
|
34
|
+
supervisors, cancel scopes, throttling, resource pools etc.
|
35
|
+
* Code can use native networking classes and libraries, growing support for
|
36
|
+
third-party gems such as `pg` and `redis`.
|
37
|
+
* Use stdlib classes such as `TCPServer`, `TCPSocket` and
|
38
|
+
`OpenSSL::SSL::SSLSocket`.
|
39
|
+
* Competitive performance and scalability characteristics, in terms of both
|
40
|
+
throughput and memory consumption.
|
41
|
+
|
42
|
+
## Documentation
|
43
|
+
|
44
|
+
The complete documentation for Polyphony could be found on the
|
45
|
+
[Polyphony website](https://digital-fabric.github.io/polyphony).
|
46
|
+
|
47
|
+
## Contributing to Polyphony
|
48
|
+
|
49
|
+
Issues and pull requests will be gladly accepted. Please use the [Polyphony git
|
50
|
+
repository](https://github.com/digital-fabric/polyphony) as your primary point
|
51
|
+
of departure for contributing.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/clean"
|
5
|
+
|
6
|
+
require "rake/extensiontask"
|
7
|
+
Rake::ExtensionTask.new("polyphony_ext") do |ext|
|
8
|
+
ext.ext_dir = "ext/polyphony"
|
9
|
+
end
|
10
|
+
|
11
|
+
task :recompile => [:clean, :compile]
|
12
|
+
|
13
|
+
task :default => [:compile, :test]
|
14
|
+
task :test do
|
15
|
+
exec 'ruby test/run.rb'
|
16
|
+
end
|
17
|
+
|
18
|
+
task :stress_test do
|
19
|
+
exec 'ruby test/stress.rb'
|
20
|
+
end
|
21
|
+
|
22
|
+
task :docs do
|
23
|
+
exec 'RUBYOPT=-W0 jekyll serve -s docs -H ec2-35-158-110-38.eu-central-1.compute.amazonaws.com'
|
24
|
+
end
|
25
|
+
|
26
|
+
CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "**/*.jar", "pkg", "tmp"
|
data/TODO.md
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
- Implement `LibevAgent#connect` API
|
2
|
+
- Reimplement ResourcePool, Channel, Mutex using Queue
|
3
|
+
-- Add `Fiber#schedule_with_priority` method, aliased by `Fiber#wakeup`
|
4
|
+
- Implement agent interface is virtual function table
|
5
|
+
- Implement proxy agent for plugging in a user-provided agent class
|
6
|
+
|
7
|
+
- Debugging
|
8
|
+
- Eat your own dogfood: need a good tool to check what's going on when some
|
9
|
+
test fails
|
10
|
+
- Needs to work with Pry (can write perhaps an extension for pry)
|
11
|
+
- First impl in Ruby using `TracePoint` API
|
12
|
+
- Mode of operation:
|
13
|
+
- Two parts: tracer and controller
|
14
|
+
- The tracer keeps state
|
15
|
+
- The controller interacts with the user and tells the tracer what to do
|
16
|
+
- Tracer and controller interact using fiber message passing
|
17
|
+
- The controller lives on a separate thread
|
18
|
+
- The tracer invokes the controller at the appropriate point in time
|
19
|
+
according to the state. For example, when doing a `next` command, the
|
20
|
+
tracer will wait for a `:line` event to occur within the same stack
|
21
|
+
frame, or for the frame to be popped on a `:return` event, and only then
|
22
|
+
will it invoke the controller.
|
23
|
+
- While invoking the controller and waiting for its reply, the tracer
|
24
|
+
optionally performs a fiber lock in order to prevent other fibers from
|
25
|
+
advancing (the fiber lock is the default mode).
|
26
|
+
- The tracer's state is completely inspectable
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
PolyTrace.state
|
30
|
+
PolyTrace.current_fiber
|
31
|
+
PolyTrace.call_stack
|
32
|
+
```
|
33
|
+
|
34
|
+
- Modes can be changed using an API, e.g.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
PolyTrace.fiber_lock = false
|
38
|
+
```
|
39
|
+
|
40
|
+
- Fibers can be interrogated using an API, or perhaps using some kind of
|
41
|
+
Pry command...
|
42
|
+
|
43
|
+
- Normal mode of operation is fiber modal, that is, trace only the currently
|
44
|
+
selected fiber. The currently selected fiber may be changed upon breakpoint
|
45
|
+
|
46
|
+
- Step over should return on the next line *for the same fiber*
|
47
|
+
- The event loop (all event loops?) should be suspended so timers are adjusted
|
48
|
+
accordingly, so on control passing to debugger we:
|
49
|
+
|
50
|
+
- call `ev_suspend()` for main thread ev_loop
|
51
|
+
- prompt and wait for input from user
|
52
|
+
- call `ev_resume()` for main thread ev_loop
|
53
|
+
- process user input
|
54
|
+
|
55
|
+
(We need to verify than `ev_suspend/resume` works for an ev_loop that's not
|
56
|
+
currently running.)
|
57
|
+
- Allow inspection of fiber tree, thread's run queue, fiber's scheduled values etc.
|
58
|
+
|
59
|
+
- UI
|
60
|
+
- `Kernel#breakpoint` is used to break into the debugger while running code
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
def test_sleep
|
64
|
+
f = spin { sleep 10 }
|
65
|
+
breakpoint
|
66
|
+
...
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Hitting the breakpoint will show the current location in the source code
|
71
|
+
(with few lines before and after), and present a prompt for commands.
|
72
|
+
|
73
|
+
- commands:
|
74
|
+
- `step` / `up` / `skip` / `continue` etc. - step into, step out, step over, run
|
75
|
+
- `switch` - switch fiber
|
76
|
+
- how do we select a fiber?
|
77
|
+
- from a list?
|
78
|
+
- from an expression: `Fiber.current.children`
|
79
|
+
- maybe just `select f1` (where f1 is a local var)
|
80
|
+
|
81
|
+
- Allow locking the scheduler on to one fiber
|
82
|
+
- Add instance var `@fiber_lock`
|
83
|
+
- API is `Thread#fiber_lock` which sets the fiber_lock instance varwhile
|
84
|
+
running the block:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
def debug_prompt
|
88
|
+
Thread.current.fiber_lock do
|
89
|
+
...
|
90
|
+
end
|
91
|
+
end
|
92
|
+
```
|
93
|
+
- When `@fiber_lock` is set, it is considered as the only one in the run
|
94
|
+
queue:
|
95
|
+
|
96
|
+
```c
|
97
|
+
VALUE fiber_lock = rb_ivar_get(self, ID_ivar_fiber_lock);
|
98
|
+
int locked = fiber_lock != Qnil;
|
99
|
+
|
100
|
+
while (1) {
|
101
|
+
next_fiber = locked ? fiber_lock : rb_ary_shift(queue);
|
102
|
+
...
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
- Docs
|
113
|
+
- landing page:
|
114
|
+
- links to the interesting stuff
|
115
|
+
- benchmarks
|
116
|
+
- explain difference between `sleep` and `suspend`
|
117
|
+
- discuss using `snooze` for ensuring responsiveness when executing CPU-bound work
|
118
|
+
|
119
|
+
|
120
|
+
## 0.44
|
121
|
+
|
122
|
+
### Some more API work, more docs
|
123
|
+
|
124
|
+
- sintra app with database access (postgresql)
|
125
|
+
|
126
|
+
- sidekiq: Plan of action
|
127
|
+
- see if we can get by just writing an adapter
|
128
|
+
- if not, fork sidekiq, make adjustments to Polyphony code
|
129
|
+
- test performance
|
130
|
+
- proceed from there
|
131
|
+
|
132
|
+
|
133
|
+
## 0.45
|
134
|
+
|
135
|
+
### Sinatra / Sidekiq
|
136
|
+
|
137
|
+
- Pull out redis/postgres code, put into new `polyphony-xxx` gems
|
138
|
+
|
139
|
+
## 0.46
|
140
|
+
|
141
|
+
### Testing && Docs
|
142
|
+
|
143
|
+
- More tests
|
144
|
+
- Implement some basic stuff missing:
|
145
|
+
- override `IO#eof?` since it too reads into buffer
|
146
|
+
- real `IO#gets` (with buffering)
|
147
|
+
- `IO#read` (read to EOF)
|
148
|
+
- `IO.foreach`
|
149
|
+
- `Process.waitpid`
|
150
|
+
|
151
|
+
## 0.47
|
152
|
+
|
153
|
+
### Real IO#gets and IO#read
|
154
|
+
|
155
|
+
## 0.48 DNS
|
156
|
+
|
157
|
+
### DNS client
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
ip_address = DNS.lookup('google.com', 'A')
|
161
|
+
```
|
162
|
+
|
163
|
+
Prior art:
|
164
|
+
|
165
|
+
- https://github.com/alexdalitz/dnsruby
|
166
|
+
- https://github.com/eventmachine/eventmachine/blob/master/lib/em/resolver.rb
|
167
|
+
- https://github.com/gmodarelli/em-resolv-replace/blob/master/lib/em-dns-resolver.rb
|
168
|
+
- https://github.com/socketry/async-dns
|
169
|
+
|
170
|
+
### DNS server
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
require 'polyphony/dns'
|
174
|
+
server = Polyphony::DNS::Server.new do |transaction|
|
175
|
+
transaction.questions.each do |q|
|
176
|
+
respond(transaction, q[:domain], q[:resource_class])
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
server.listen(port: 5300)
|
181
|
+
puts "listening on port 5300"
|
182
|
+
```
|
183
|
+
|
184
|
+
Prior art:
|
185
|
+
|
186
|
+
- https://github.com/socketry/async-dns
|
187
|
+
|
188
|
+
## Work on API
|
189
|
+
|
190
|
+
- Add option for setting the exception raised on cancelling using `#cancel_after`:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
cancel_after(3, with_error: MyErrorClass) do
|
194
|
+
do_my_thing
|
195
|
+
end
|
196
|
+
# or a RuntimeError with message
|
197
|
+
cancel_after(3, with_error: 'Cancelled due to timeout') do
|
198
|
+
do_my_thing
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|