polyphony 0.17 → 0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +11 -3
- data/README.md +18 -18
- data/TODO.md +5 -21
- data/examples/core/channel_echo.rb +3 -3
- data/examples/core/enumerator.rb +1 -1
- data/examples/core/fork.rb +1 -1
- data/examples/core/genserver.rb +1 -1
- data/examples/core/lock.rb +3 -3
- data/examples/core/multiple_spawn.rb +2 -2
- data/examples/core/nested_async.rb +1 -1
- data/examples/core/nested_multiple_spawn.rb +3 -3
- data/examples/core/resource_cancel.rb +1 -1
- data/examples/core/sleep_spawn.rb +2 -2
- data/examples/core/spawn.rb +1 -1
- data/examples/core/spawn_cancel.rb +1 -1
- data/examples/core/spawn_error.rb +4 -4
- data/examples/core/supervisor.rb +1 -1
- data/examples/core/supervisor_with_error.rb +1 -1
- data/examples/core/supervisor_with_manual_move_on.rb +1 -1
- data/examples/core/thread.rb +2 -2
- data/examples/core/thread_cancel.rb +2 -2
- data/examples/core/thread_pool.rb +1 -1
- data/examples/core/throttle.rb +3 -3
- data/examples/core/timeout.rb +10 -0
- data/examples/fs/read.rb +1 -1
- data/examples/http/http_client.rb +1 -1
- data/examples/http/http_get.rb +7 -0
- data/examples/http/http_parse_experiment.rb +118 -0
- data/examples/http/http_proxy.rb +81 -0
- data/examples/http/http_server.rb +15 -4
- data/examples/http/http_server_forked.rb +2 -2
- data/examples/http/http_server_throttled.rb +1 -1
- data/examples/http/http_ws_server.rb +2 -2
- data/examples/http/https_server.rb +5 -1
- data/examples/http/https_wss_server.rb +1 -1
- data/examples/http/rack_server_https_forked.rb +1 -1
- data/examples/interfaces/pg_client.rb +1 -1
- data/examples/interfaces/pg_pool.rb +1 -1
- data/examples/interfaces/redis_channels.rb +5 -5
- data/examples/interfaces/redis_pubsub.rb +2 -2
- data/examples/interfaces/redis_pubsub_perf.rb +3 -3
- data/examples/io/echo_client.rb +2 -2
- data/examples/io/echo_pipe.rb +17 -0
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_with_timeout.rb +1 -1
- data/examples/io/httparty.rb +10 -0
- data/examples/io/httparty_multi.rb +29 -0
- data/examples/io/httparty_threaded.rb +25 -0
- data/examples/io/irb.rb +15 -0
- data/examples/io/net-http.rb +15 -0
- data/examples/io/system.rb +1 -1
- data/examples/io/tcpsocket.rb +18 -0
- data/examples/performance/perf_multi_snooze.rb +2 -2
- data/examples/performance/perf_snooze.rb +17 -20
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -1
- data/ext/ev/ev.h +9 -1
- data/ext/ev/ev_ext.c +4 -1
- data/ext/ev/ev_module.c +36 -22
- data/ext/ev/extconf.rb +1 -1
- data/ext/ev/io.c +23 -23
- data/ext/ev/signal.c +1 -1
- data/ext/ev/socket.c +161 -0
- data/lib/polyphony/core/coprocess.rb +1 -1
- data/lib/polyphony/core/fiber_pool.rb +2 -2
- data/lib/polyphony/core/supervisor.rb +2 -18
- data/lib/polyphony/extensions/io.rb +19 -6
- data/lib/polyphony/extensions/kernel.rb +17 -5
- data/lib/polyphony/extensions/socket.rb +40 -1
- data/lib/polyphony/http/agent.rb +56 -25
- data/lib/polyphony/http/http1_adapter.rb +254 -0
- data/lib/polyphony/http/http2_adapter.rb +157 -0
- data/lib/polyphony/http/{http2_request.rb → request.rb} +25 -22
- data/lib/polyphony/http/server.rb +19 -11
- data/lib/polyphony/net.rb +10 -6
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +6 -5
- data/test/test_coprocess.rb +9 -9
- data/test/test_core.rb +14 -14
- data/test/test_io.rb +4 -4
- data/test/test_kernel.rb +1 -1
- metadata +48 -23
- data/lib/polyphony/http/http1.rb +0 -124
- data/lib/polyphony/http/http1_request.rb +0 -83
- data/lib/polyphony/http/http2.rb +0 -65
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e79ca0a896fc0b5feffa415e44b9229074d145c2142155caf47f243b6c85078d
|
4
|
+
data.tar.gz: 6aa58f404376be6e6d472e588be4349d6fcaeb3031e5786a0a5ffe0970d9fa5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: accbeddc33fd7b1de40f411a421c445bc847e8ee744d98dcd1cf20b0a8fe3fc5c880ca373a020b026a0d68aac9cfc74f179bde2c3cebd1b0733a5adbe2b435b0
|
7
|
+
data.tar.gz: 7549c7ac4528bf4747049fb6c4eecbfe500f6aeed3586f8181bbf21506f8725ebb51c1170e369f15b24c748d59be439a2d076d26de1e5b1a1b6b34ae3e344ade
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
0.19 2019-06-12
|
2
|
+
---------------
|
3
|
+
|
4
|
+
* Rewrite HTTP server for better concurrency, sequential API
|
5
|
+
* Support 204 no-content response in HTTP 1
|
6
|
+
* Add optional count parameter to Kernel#throttled_loop for finite looping
|
7
|
+
* Implement Fiber#safe_transfer in C
|
8
|
+
* Optimize Kernel#next_tick implementation using ev_idle instead of ev_timer
|
9
|
+
|
10
|
+
0.18 2019-06-08
|
11
|
+
---------------
|
12
|
+
|
13
|
+
* Rename Kernel#coproc to Kernel#spin
|
14
|
+
* Rewrite Supervisor#spin
|
15
|
+
|
1
16
|
0.17 2019-05-24
|
2
17
|
---------------
|
3
18
|
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
polyphony (0.
|
4
|
+
polyphony (0.19)
|
5
5
|
http-2 (= 0.10.0)
|
6
6
|
http_parser.rb (= 0.6.0)
|
7
|
-
modulation (
|
7
|
+
modulation (~> 0.25)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
@@ -12,9 +12,16 @@ GEM
|
|
12
12
|
hiredis (0.6.3)
|
13
13
|
http-2 (0.10.0)
|
14
14
|
http_parser.rb (0.6.0)
|
15
|
+
httparty (0.17.0)
|
16
|
+
mime-types (~> 3.0)
|
17
|
+
multi_xml (>= 0.5.2)
|
15
18
|
localhost (1.1.4)
|
19
|
+
mime-types (3.2.2)
|
20
|
+
mime-types-data (~> 3.2015)
|
21
|
+
mime-types-data (3.2019.0331)
|
16
22
|
minitest (5.11.3)
|
17
|
-
modulation (0.
|
23
|
+
modulation (0.25)
|
24
|
+
multi_xml (0.6.0)
|
18
25
|
pg (1.1.3)
|
19
26
|
rake (12.3.2)
|
20
27
|
rake-compiler (1.0.5)
|
@@ -27,6 +34,7 @@ PLATFORMS
|
|
27
34
|
|
28
35
|
DEPENDENCIES
|
29
36
|
hiredis (= 0.6.3)
|
37
|
+
httparty (= 0.17.0)
|
30
38
|
localhost (= 1.1.4)
|
31
39
|
minitest (= 5.11.3)
|
32
40
|
pg (= 1.1.3)
|
data/README.md
CHANGED
@@ -11,8 +11,8 @@
|
|
11
11
|
> number of parts, each forming an individual melody and harmonizing with each
|
12
12
|
> other.
|
13
13
|
|
14
|
-
**Note**: Polyphony is designed to work with recent
|
15
|
-
|
14
|
+
**Note**: Polyphony is experimental software. It is designed to work with recent
|
15
|
+
versions of Ruby (2.5 and newer) and supports Linux and MacOS only.
|
16
16
|
|
17
17
|
## What is Polyphony
|
18
18
|
|
@@ -41,7 +41,7 @@ takes care of context-switching automatically whenever a blocking call like
|
|
41
41
|
coprocesses, supervisors, cancel scopes, throttling, resource pools etc.
|
42
42
|
- Code can use native networking classes and libraries, growing support for
|
43
43
|
third-party gems such as `pg` and `redis`.
|
44
|
-
- HTTP 1 / HTTP 2 client
|
44
|
+
- HTTP 1 / HTTP 2 client agent with persistent connections.
|
45
45
|
- Competitive performance and scalability characteristics, in terms of both
|
46
46
|
throughput and memory consumption.
|
47
47
|
|
@@ -70,18 +70,18 @@ The reactor, in turn, may schedule other operations once they can be resumed. In
|
|
70
70
|
that manner, multiple ongoing operations may be processed concurrently.
|
71
71
|
|
72
72
|
There are multiple ways to start a concurrent operation, the most common of
|
73
|
-
which is `Kernel#
|
73
|
+
which is `Kernel#spin`:
|
74
74
|
|
75
75
|
```ruby
|
76
76
|
require 'polyphony'
|
77
77
|
|
78
|
-
|
78
|
+
spin do
|
79
79
|
puts "A going to sleep"
|
80
80
|
sleep 1
|
81
81
|
puts "A woken up"
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
spin do
|
85
85
|
puts "B going to sleep"
|
86
86
|
sleep 1
|
87
87
|
puts "B woken up"
|
@@ -90,7 +90,7 @@ end
|
|
90
90
|
|
91
91
|
In the above example, both `sleep` calls will be executed concurrently, and thus
|
92
92
|
the program will take approximately only 1 second to execute. Note the lack of
|
93
|
-
any boilerplate relating to concurrency. Each `
|
93
|
+
any boilerplate relating to concurrency. Each `spin` block starts a
|
94
94
|
*coprocess*, and is executed in sequential manner.
|
95
95
|
|
96
96
|
> **Coprocesses - the basic unit of concurrency**: In Polyphony, concurrent
|
@@ -99,8 +99,8 @@ any boilerplate relating to concurrency. Each `coproc` block starts a
|
|
99
99
|
> called, and resumed once that operation has been completed. Coprocesses offer
|
100
100
|
> significant advantages over threads - they consume only about 10KB, switching
|
101
101
|
> between them is much faster than switching threads, and literally millions of
|
102
|
-
> them can be
|
103
|
-
> allow parallel execution of threads.
|
102
|
+
> them can be spinned off without affecting performance*. Besides, Ruby does not
|
103
|
+
> yet allow parallel execution of threads (courtesy of the Ruby GVL).
|
104
104
|
>
|
105
105
|
> \* *This is a totally unsubstantiated claim which has not been proved in
|
106
106
|
> practice*.
|
@@ -116,7 +116,7 @@ require 'polyphony'
|
|
116
116
|
server = TCPServer.open(1234)
|
117
117
|
while client = server.accept
|
118
118
|
# coproc starts a new coprocess on a separate fiber
|
119
|
-
|
119
|
+
spin {
|
120
120
|
while data = client.read rescue nil
|
121
121
|
client.write(data)
|
122
122
|
end
|
@@ -129,7 +129,7 @@ This example demonstrates several features of Polyphony:
|
|
129
129
|
- The code uses the native `TCPServer` class from Ruby's stdlib, to setup a TCP
|
130
130
|
server. The result of `server.accept` is also a native `TCPSocket` object.
|
131
131
|
There are no wrapper classes being used.
|
132
|
-
- The only hint of the code being concurrent is the use of `Kernel#
|
132
|
+
- The only hint of the code being concurrent is the use of `Kernel#spin`,
|
133
133
|
which starts a new coprocess on a dedicated fiber. This allows serving
|
134
134
|
multiple clients at once. Whenever a blocking call is issued, such as
|
135
135
|
`#accept` or `#read`, execution is *yielded* to the event loop, which will
|
@@ -223,7 +223,7 @@ end
|
|
223
223
|
### Additional concurrency constructs
|
224
224
|
|
225
225
|
In order to facilitate writing concurrent code, Polyphony provides additional
|
226
|
-
constructs that make it easier to
|
226
|
+
constructs that make it easier to create and control concurrent tasks.
|
227
227
|
|
228
228
|
`CancelScope` - an abstraction used to cancel the execution of one or more
|
229
229
|
coprocesses or supervisors. It usually works by defining a timeout for the
|
@@ -257,7 +257,7 @@ Pool = Polyphony::ResourcePool.new(limit: 5) {
|
|
257
257
|
}
|
258
258
|
|
259
259
|
1000.times {
|
260
|
-
|
260
|
+
spin {
|
261
261
|
Pool.acquire { |db| p db.query('select 1') }
|
262
262
|
}
|
263
263
|
}
|
@@ -274,7 +274,7 @@ Pool = Polyphony::ResourcePool.new(limit: 5) {
|
|
274
274
|
}
|
275
275
|
|
276
276
|
1000.times {
|
277
|
-
|
277
|
+
spin { p Pool.query('select 1') }
|
278
278
|
}
|
279
279
|
```
|
280
280
|
|
@@ -285,9 +285,9 @@ using `Kernel.supervise`:
|
|
285
285
|
|
286
286
|
```ruby
|
287
287
|
supervise { |s|
|
288
|
-
s.
|
289
|
-
s.
|
290
|
-
s.
|
288
|
+
s.spin { sleep 1 }
|
289
|
+
s.spin { sleep 2 }
|
290
|
+
s.spin { sleep 3 }
|
291
291
|
}
|
292
292
|
puts "done sleeping"
|
293
293
|
```
|
@@ -313,7 +313,7 @@ server = Net.tcp_listen(1234)
|
|
313
313
|
throttler = throttle(rate: 10) # up to 10 times per second
|
314
314
|
|
315
315
|
while client = server.accept
|
316
|
-
|
316
|
+
spin {
|
317
317
|
throttler.call {
|
318
318
|
while data = client.read
|
319
319
|
client.write(data)
|
data/TODO.md
CHANGED
@@ -1,42 +1,26 @@
|
|
1
1
|
# Roadmap:
|
2
2
|
|
3
|
-
## 0.
|
4
|
-
|
5
|
-
- Don't worry about performance or completeness of behaviour
|
6
|
-
- Related global functions such as:
|
7
|
-
- `Kernel#system`
|
8
|
-
- `IO.popen`
|
9
|
-
- testing - check conformance to Ruby `IO` API (arguments and return values as
|
10
|
-
described in the Ruby docs)
|
11
|
-
|
12
|
-
## 0.18 Working net/http, httparty
|
13
|
-
|
14
|
-
- implement `TCPSocket`/`TCPServer` functionality
|
15
|
-
- test `socket` classes
|
16
|
-
- test `Net::HTTP`
|
17
|
-
- test `httparty`
|
18
|
-
|
19
|
-
## 0.19 Full Rack adapter implementation
|
3
|
+
## 0.20 Full Rack adapter implementation
|
20
4
|
|
21
5
|
- follow Rack specification (doesn't have to include stuff like streaming or
|
22
6
|
websockets)
|
23
7
|
- find some demo Rack apps and test with Polyphony
|
24
8
|
|
25
|
-
## 0.
|
9
|
+
## 0.21 Working Rails application
|
26
10
|
|
27
11
|
- app with database access (postgresql)
|
28
12
|
- benchmarks!
|
29
13
|
|
30
|
-
## 0.
|
14
|
+
## 0.22 Support for multi-threading
|
31
15
|
|
32
16
|
- Separate event loop for each thread
|
33
17
|
|
34
|
-
## 0.
|
18
|
+
## 0.23 Testing
|
35
19
|
|
36
20
|
- test thread / thread_pool modules
|
37
21
|
- report test coverage
|
38
22
|
|
39
|
-
## 0.
|
23
|
+
## 0.24 Documentation
|
40
24
|
|
41
25
|
# DNS
|
42
26
|
|
@@ -14,9 +14,9 @@ end
|
|
14
14
|
|
15
15
|
chan1, chan2 = Polyphony::Channel.new, Polyphony::Channel.new
|
16
16
|
|
17
|
-
echoer =
|
17
|
+
echoer = spin { echo(chan1, chan2) }
|
18
18
|
|
19
|
-
|
19
|
+
spin do
|
20
20
|
puts "start receiver"
|
21
21
|
while msg = chan2.receive
|
22
22
|
puts msg
|
@@ -26,7 +26,7 @@ ensure
|
|
26
26
|
puts "receiver stopped"
|
27
27
|
end
|
28
28
|
|
29
|
-
$main =
|
29
|
+
$main = spin do
|
30
30
|
t0 = Time.now
|
31
31
|
puts "send hello"
|
32
32
|
chan1 << "hello"
|
data/examples/core/enumerator.rb
CHANGED
data/examples/core/fork.rb
CHANGED
data/examples/core/genserver.rb
CHANGED
data/examples/core/lock.rb
CHANGED
data/examples/core/spawn.rb
CHANGED
@@ -9,11 +9,11 @@ def error(t)
|
|
9
9
|
raise "hello #{t}"
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def spin_with_error
|
13
|
+
spin { error(2) }
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
spin do
|
17
17
|
error(1)
|
18
18
|
rescue => e
|
19
19
|
e.cleanup_backtrace
|
@@ -23,6 +23,6 @@ rescue => e
|
|
23
23
|
puts
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
spin_with_error
|
27
27
|
|
28
28
|
puts "done coprocing"
|
data/examples/core/supervisor.rb
CHANGED