polyphony 0.22 → 0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +9 -1
- data/TODO.md +13 -38
- data/docs/summary.md +19 -5
- data/docs/technical-overview/faq.md +12 -0
- data/examples/core/01-spinning-up-coprocesses.rb +2 -6
- data/examples/core/02-awaiting-coprocesses.rb +3 -1
- data/examples/core/03-interrupting.rb +3 -1
- data/examples/core/04-no-auto-run.rb +1 -3
- data/examples/core/cancel.rb +1 -1
- data/examples/core/channel_echo.rb +3 -1
- data/examples/core/defer.rb +3 -1
- data/examples/core/enumerator.rb +3 -1
- data/examples/core/error_bubbling.rb +35 -0
- data/examples/core/fork.rb +1 -1
- data/examples/core/genserver.rb +1 -1
- data/examples/core/lock.rb +3 -1
- data/examples/core/move_on.rb +1 -1
- data/examples/core/move_on_twice.rb +1 -1
- data/examples/core/move_on_with_ensure.rb +1 -1
- data/examples/core/move_on_with_value.rb +1 -1
- data/examples/core/multiple_spin.rb +3 -1
- data/examples/core/nested_cancel.rb +1 -1
- data/examples/core/nested_multiple_spin.rb +3 -1
- data/examples/core/nested_spin.rb +3 -1
- data/examples/core/pulse.rb +1 -1
- data/examples/core/resource.rb +1 -1
- data/examples/core/resource_cancel.rb +2 -2
- data/examples/core/resource_delegate.rb +1 -1
- data/examples/core/sleep.rb +1 -1
- data/examples/core/sleep_spin.rb +3 -1
- data/examples/core/snooze.rb +1 -1
- data/examples/core/spin_error.rb +2 -1
- data/examples/core/spin_error_backtrace.rb +1 -1
- data/examples/core/spin_uncaught_error.rb +3 -1
- data/examples/core/supervisor.rb +1 -1
- data/examples/core/supervisor_with_cancel_scope.rb +1 -1
- data/examples/core/supervisor_with_error.rb +3 -1
- data/examples/core/supervisor_with_manual_move_on.rb +1 -1
- data/examples/core/suspend.rb +1 -1
- data/examples/core/thread.rb +3 -3
- data/examples/core/thread_cancel.rb +6 -3
- data/examples/core/thread_pool.rb +8 -52
- data/examples/core/thread_pool_perf.rb +63 -0
- data/examples/core/throttle.rb +3 -1
- data/examples/core/timeout.rb +1 -1
- data/examples/core/wait_for_signal.rb +4 -2
- data/examples/fs/read.rb +1 -1
- data/examples/http/http2_raw.rb +1 -1
- data/examples/http/http_get.rb +1 -1
- data/examples/http/http_server.rb +2 -1
- data/examples/http/http_server_graceful.rb +3 -1
- data/examples/http/http_ws_server.rb +0 -2
- data/examples/http/https_wss_server.rb +0 -2
- data/examples/http/websocket_secure_server.rb +0 -2
- data/examples/http/websocket_server.rb +0 -2
- data/examples/interfaces/redis_channels.rb +3 -1
- data/examples/interfaces/redis_pubsub.rb +3 -1
- data/examples/interfaces/redis_pubsub_perf.rb +3 -1
- data/examples/io/backticks.rb +1 -1
- data/examples/io/cat.rb +1 -1
- data/examples/io/echo_client.rb +1 -1
- data/examples/io/echo_client_from_stdin.rb +3 -1
- data/examples/io/echo_pipe.rb +1 -1
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_with_timeout.rb +1 -1
- data/examples/io/echo_stdin.rb +1 -1
- data/examples/io/httparty_multi.rb +1 -1
- data/examples/io/io_read.rb +1 -1
- data/examples/io/irb.rb +1 -1
- data/examples/io/net-http.rb +1 -1
- data/examples/io/open.rb +1 -1
- data/examples/io/system.rb +1 -1
- data/examples/io/tcpserver.rb +1 -1
- data/examples/io/tcpsocket.rb +1 -1
- data/examples/performance/multi_snooze.rb +1 -1
- data/examples/performance/snooze.rb +18 -10
- data/ext/gyro/async.c +16 -9
- data/ext/gyro/child.c +2 -2
- data/ext/gyro/gyro.c +17 -10
- data/ext/gyro/gyro.h +2 -2
- data/ext/gyro/io.c +2 -2
- data/ext/gyro/signal.c +33 -35
- data/ext/gyro/timer.c +6 -73
- data/lib/polyphony.rb +6 -8
- data/lib/polyphony/core/cancel_scope.rb +32 -21
- data/lib/polyphony/core/coprocess.rb +26 -23
- data/lib/polyphony/core/global_api.rb +86 -0
- data/lib/polyphony/core/resource_pool.rb +1 -1
- data/lib/polyphony/core/supervisor.rb +47 -13
- data/lib/polyphony/core/thread.rb +10 -36
- data/lib/polyphony/core/thread_pool.rb +6 -26
- data/lib/polyphony/extensions/core.rb +30 -100
- data/lib/polyphony/extensions/io.rb +10 -7
- data/lib/polyphony/extensions/openssl.rb +18 -28
- data/lib/polyphony/http/client/agent.rb +15 -11
- data/lib/polyphony/http/client/http2.rb +1 -1
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +1 -0
- data/test/coverage.rb +45 -0
- data/test/helper.rb +15 -5
- data/test/test_async.rb +4 -4
- data/test/test_cancel_scope.rb +109 -0
- data/test/test_coprocess.rb +80 -36
- data/test/{test_core.rb → test_global_api.rb} +67 -13
- data/test/test_gyro.rb +1 -5
- data/test/test_io.rb +2 -2
- data/test/test_resource_pool.rb +19 -0
- data/test/test_signal.rb +10 -5
- data/test/test_supervisor.rb +168 -0
- data/test/test_timer.rb +31 -5
- metadata +23 -4
- data/lib/polyphony/auto_run.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42975a9e638525d2264fbddea88ee0756fb7e7dbc5c0585c033b71a06a27711c
|
4
|
+
data.tar.gz: 2c233b91c02d60e1dc40fbacb1dbade17c591a9ddede854e71dc7b2a840dcfd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 339373f341a10fa68bec7d39588407519c12e17f9b02f774b9179af9b682512c156aa254cac116d4f60d1528e4dae21cfe220e71bf998787c0f1b55c244ef959
|
7
|
+
data.tar.gz: 429a5960bbc3a38d23282ab1a8339b1ae556832fd098e34ae1a63fca36f4bc9f15f8996a715c70ac3363e01ea1858c2cf9de6b9296e90cf7f6a6c8a79f42c48c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
0.23 2020-01-07
|
2
|
+
---------------
|
3
|
+
|
4
|
+
* Remove `API#pulse`
|
5
|
+
* Better repeat timer, reimplement `API#every`
|
6
|
+
* Move global API methods to separate module, include in `Object` instead of
|
7
|
+
`Kernel`
|
8
|
+
* Improve setting root fiber and corresponding coprocess
|
9
|
+
* Fix `ResourcePool#preheat!`
|
10
|
+
* Rename `$Coprocess#list` to `Coprocess#map`
|
11
|
+
* Fix `CancelScope#on_cancel`, remove `CancelScope#protect`
|
12
|
+
* Remove `auto_run` mechanism. Just use `suspend`!
|
13
|
+
* Optional coverage report for tests
|
14
|
+
* More tests
|
15
|
+
* Add `Coprocess.select` and `Supervisor#select` methods
|
16
|
+
* Add `Coprocess.join` alias to `Coprocess.await` method
|
17
|
+
* Add support for cancelling multiple coprocesses with a single cancel scope
|
18
|
+
* Fix stopping a coprocess before it being scheduled for the first time
|
19
|
+
* Rewrite `thread`, `thread_pool` modules
|
20
|
+
* Add `Kernel#orig_sleep` alias to sync `#sleep` method
|
21
|
+
* Add optional resume value to `Gyro::Async#signal!`
|
22
|
+
* Patch Fiber#inspect to show correct block location
|
23
|
+
* Add Gyro.run
|
24
|
+
* Move away from callback-based API for `Gyro::Timer`, `Gyro::Signal`
|
25
|
+
|
1
26
|
0.22 2020-01-02
|
2
27
|
---------------
|
3
28
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
polyphony (0.
|
4
|
+
polyphony (0.23)
|
5
5
|
http-2 (= 0.10.0)
|
6
6
|
http_parser.rb (= 0.6.0)
|
7
7
|
modulation (~> 0.25)
|
@@ -12,12 +12,14 @@ GEM
|
|
12
12
|
specs:
|
13
13
|
ansi (1.5.0)
|
14
14
|
builder (3.2.4)
|
15
|
+
docile (1.3.2)
|
15
16
|
hiredis (0.6.3)
|
16
17
|
http-2 (0.10.0)
|
17
18
|
http_parser.rb (0.6.0)
|
18
19
|
httparty (0.17.0)
|
19
20
|
mime-types (~> 3.0)
|
20
21
|
multi_xml (>= 0.5.2)
|
22
|
+
json (2.1.0)
|
21
23
|
localhost (1.1.4)
|
22
24
|
mime-types (3.3.1)
|
23
25
|
mime-types-data (~> 3.2015)
|
@@ -37,6 +39,11 @@ GEM
|
|
37
39
|
rake
|
38
40
|
redis (4.1.0)
|
39
41
|
ruby-progressbar (1.10.1)
|
42
|
+
simplecov (0.17.1)
|
43
|
+
docile (~> 1.1)
|
44
|
+
json (>= 1.8, < 3)
|
45
|
+
simplecov-html (~> 0.10.0)
|
46
|
+
simplecov-html (0.10.2)
|
40
47
|
websocket (1.2.8)
|
41
48
|
|
42
49
|
PLATFORMS
|
@@ -52,6 +59,7 @@ DEPENDENCIES
|
|
52
59
|
polyphony!
|
53
60
|
rake-compiler (= 1.0.5)
|
54
61
|
redis (= 4.1.0)
|
62
|
+
simplecov (= 0.17.1)
|
55
63
|
websocket (= 1.2.8)
|
56
64
|
|
57
65
|
BUNDLED WITH
|
data/TODO.md
CHANGED
@@ -1,31 +1,3 @@
|
|
1
|
-
# Add ability to cancel multiple coprocesses
|
2
|
-
|
3
|
-
```ruby
|
4
|
-
scope = CancelScope.new
|
5
|
-
|
6
|
-
3.times { |i|
|
7
|
-
spin {
|
8
|
-
puts "sleep for #{i + 1}s"
|
9
|
-
scope.call { sleep i + 1 }
|
10
|
-
puts "woke up"
|
11
|
-
}
|
12
|
-
}
|
13
|
-
|
14
|
-
sleep 0.5
|
15
|
-
scope.cancel!
|
16
|
-
```
|
17
|
-
|
18
|
-
# Add ability to wait for signal
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
sig = Gyro::Signal('SIGUP')
|
22
|
-
|
23
|
-
loop do
|
24
|
-
sig.await
|
25
|
-
restart
|
26
|
-
end
|
27
|
-
```
|
28
|
-
|
29
1
|
# HTTP Client Agent
|
30
2
|
|
31
3
|
The concurrency model and the fact that we want to serve the response object on
|
@@ -71,14 +43,12 @@ end
|
|
71
43
|
|
72
44
|
# Roadmap:
|
73
45
|
|
74
|
-
## 0.
|
46
|
+
## 0.24 Move HTTP code into separate gem
|
75
47
|
|
76
|
-
-
|
77
|
-
-
|
78
|
-
- Scheduled fibers managed using linked list, switching directly from one to the
|
79
|
-
other
|
48
|
+
- Pull out HTTP/websocket code, put into new `polyphony-http` gem
|
49
|
+
- Pull out redis/postgres code, put into new `polyphony-contrib` gem
|
80
50
|
|
81
|
-
## 0.
|
51
|
+
## 0.25 Full Rack adapter implementation
|
82
52
|
|
83
53
|
- Work better mechanism supervising multiple coprocesses (`when_done` feels a
|
84
54
|
bit hacky)
|
@@ -86,21 +56,26 @@ end
|
|
86
56
|
- Homogenize HTTP 1 and HTTP 2 headers - upcase ? downcase ?
|
87
57
|
- find some demo Rack apps and test with Polyphony
|
88
58
|
|
89
|
-
## 0.
|
59
|
+
## 0.26 Working Sinatra application
|
90
60
|
|
91
61
|
- app with database access (postgresql)
|
92
62
|
- benchmarks!
|
93
63
|
|
94
|
-
## 0.
|
64
|
+
## 0.27 Support for multi-threading
|
95
65
|
|
96
66
|
- Separate event loop for each thread
|
97
67
|
|
98
|
-
## 0.
|
68
|
+
## 0.28 Testing
|
99
69
|
|
100
70
|
- test thread / thread_pool modules
|
101
71
|
- report test coverage
|
102
72
|
|
103
|
-
## 0.
|
73
|
+
## 0.29 Documentation
|
74
|
+
|
75
|
+
## 0.30 Integration
|
76
|
+
|
77
|
+
- Sidekick
|
78
|
+
- Rails?
|
104
79
|
|
105
80
|
# DNS
|
106
81
|
|
data/docs/summary.md
CHANGED
@@ -15,11 +15,25 @@
|
|
15
15
|
* [Exception Handling](technical-overview/exception-handling.md)
|
16
16
|
* [Frequently Asked Questions](technical-overview/faq.md)
|
17
17
|
|
18
|
-
##
|
19
|
-
|
20
|
-
* [
|
21
|
-
* [
|
22
|
-
* [
|
18
|
+
## How To
|
19
|
+
|
20
|
+
* [Make an echo server](howto/echo-server.md)
|
21
|
+
* [Make an HTTP server](howto/http-server.md)
|
22
|
+
* [Make a Websocket server](howto/websocket-server.md)
|
23
|
+
* [Use timers](howto/timers.md)
|
24
|
+
* [Throttle recurrent operations](howto/throttle.md)
|
25
|
+
* [Cancel ongoing operations](howto/cancel.md)
|
26
|
+
* [Control coprocesses](howto/coprocesses.md)
|
27
|
+
* [Synchronize concurrent operations](howto/synchronize.md)
|
28
|
+
* [Perform CPU-bound operations](howto/cpu-bound.md)
|
29
|
+
* [Control backpressure](howto/backpressure.md)
|
30
|
+
* [Fork worker processes](howto/worker-processes.md)
|
31
|
+
|
32
|
+
## Polyphony extensions
|
33
|
+
|
34
|
+
* [Postgresql](extensions/pg)
|
35
|
+
* [Redis](extensions/redis)
|
36
|
+
* [IRB](extensions/irb)
|
23
37
|
* [Throttlers](#)
|
24
38
|
* [Resource Pools](#)
|
25
39
|
* [Synchronisation](#)
|
@@ -80,6 +80,18 @@ The API for `Fiber.yield`/`Fiber#resume` is stateful and is intended for the asy
|
|
80
80
|
|
81
81
|
Polyphony is currently at an experimental stage, and its different APIs are still in flux. For that reason, all the different parts of Polyphony are currently kept in a single gem. Once things stabilize, and as Polyphony approaches version 1.0, it will be split into separate gems, each with its own functionality.
|
82
82
|
|
83
|
+
## Can I use Polyphony in a multithreaded program?
|
84
|
+
|
85
|
+
Not yet. We plan to support multiple threads when Ruby 3.0 is ready.
|
86
|
+
|
87
|
+
## Can I run Rails using Polyphony?
|
88
|
+
|
89
|
+
Not yet. We do plan to support running Rails when our multithreaded support is ready (see above).
|
90
|
+
|
91
|
+
## How can I contribute to Polyphony?
|
92
|
+
|
93
|
+
The Polyphony repository is at https://github.com/digital-fabric/polyphony. Feel free to create issues and contribute pull requests.
|
94
|
+
|
83
95
|
## Who is behind this project?
|
84
96
|
|
85
97
|
I'm Sharon Rosner, an independent software developer living in France. Here's my [github profile](https://github.com/ciconia). You can contact me by writing to [noteflakes@gmail.com](mailto:ciconia@gmail.com).
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
|
5
|
-
|
6
|
-
# `polyphony/auto_run`. Otherwise, we can just require `polyphony`
|
7
|
-
require 'polyphony/auto_run'
|
5
|
+
require 'polyphony'
|
8
6
|
|
9
7
|
def nap(tag, t)
|
10
8
|
puts "#{Time.now} #{tag} napping for #{t} seconds..."
|
@@ -16,6 +14,4 @@ end
|
|
16
14
|
spin { nap(:a, 1) }
|
17
15
|
spin { nap(:b, 2) }
|
18
16
|
|
19
|
-
|
20
|
-
# libev-based event reactor is started, and runs until there's no more work left
|
21
|
-
# for it to handle.
|
17
|
+
suspend
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
|
6
6
|
sleeper = spin do
|
7
7
|
puts 'going to sleep'
|
@@ -16,3 +16,5 @@ waiter = spin do
|
|
16
16
|
sleeper.await
|
17
17
|
puts 'done waiting'
|
18
18
|
end
|
19
|
+
|
20
|
+
waiter.await
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
|
6
6
|
# Let's see how a long-running blocking operation can be interrupted. Polyphony
|
7
7
|
# provides several APIs for interrupting an ongoing operation, and distinguishes
|
@@ -32,3 +32,5 @@ spin do
|
|
32
32
|
nap(:move_on, 2)
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
suspend
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
|
5
|
-
# Notice we require 'polyphony' and not 'polyphony/auto_run'
|
6
5
|
require 'polyphony'
|
7
6
|
|
8
7
|
def nap(tag, t)
|
@@ -13,6 +12,5 @@ end
|
|
13
12
|
|
14
13
|
spin { nap(:a, 1) }
|
15
14
|
|
16
|
-
#
|
17
|
-
# started manually. This is done by transferring control to it using `suspend`:
|
15
|
+
# Wait for any coprocess still alive
|
18
16
|
suspend
|
data/examples/core/cancel.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
|
6
6
|
def echo(cin, cout)
|
7
7
|
puts 'start echoer'
|
@@ -41,3 +41,5 @@ $main = spin do
|
|
41
41
|
chan2.close
|
42
42
|
puts "done #{Time.now - t0}"
|
43
43
|
end
|
44
|
+
|
45
|
+
suspend
|
data/examples/core/defer.rb
CHANGED
data/examples/core/enumerator.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
|
6
|
+
::Exception.__disable_sanitized_backtrace__ = true
|
7
|
+
|
8
|
+
def test
|
9
|
+
# error is propagated to calling coprocess
|
10
|
+
raised_error = nil
|
11
|
+
spin do
|
12
|
+
spin do
|
13
|
+
raise 'foo'
|
14
|
+
end
|
15
|
+
puts "before snooze"
|
16
|
+
snooze # allow nested coprocess to run before finishing
|
17
|
+
puts "after snooze"
|
18
|
+
end
|
19
|
+
suspend
|
20
|
+
rescue Exception => e
|
21
|
+
raised_error = e
|
22
|
+
ensure
|
23
|
+
puts "raised_error: #{raised_error.inspect}"
|
24
|
+
# puts "msg: #{raised_error.message.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
test
|
28
|
+
begin
|
29
|
+
puts "last suspend"
|
30
|
+
#suspend
|
31
|
+
Gyro.run
|
32
|
+
rescue => e
|
33
|
+
puts "!" * 60
|
34
|
+
puts "Error after last suspend: #{e.inspect}"
|
35
|
+
end
|
data/examples/core/fork.rb
CHANGED
data/examples/core/genserver.rb
CHANGED
data/examples/core/lock.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony
|
4
|
+
require 'polyphony'
|
5
5
|
|
6
6
|
def loop_it(number, lock)
|
7
7
|
loop do
|
@@ -17,3 +17,5 @@ lock = Polyphony::Sync::Mutex.new
|
|
17
17
|
spin { loop_it(1, lock) }
|
18
18
|
spin { loop_it(2, lock) }
|
19
19
|
spin { loop_it(3, lock) }
|
20
|
+
|
21
|
+
suspend
|
data/examples/core/move_on.rb
CHANGED