polyphony 0.23 → 0.24
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +4 -10
- data/README.md +0 -4
- data/TODO.md +5 -56
- data/docs/README.md +4 -7
- data/examples/core/{channel_echo.rb → xx-channels.rb} +0 -0
- data/examples/core/{defer.rb → xx-deferring-an-operation.rb} +0 -0
- data/examples/core/{genserver.rb → xx-erlang-style-genserver.rb} +2 -2
- data/examples/core/{fork.rb → xx-forking.rb} +2 -0
- data/examples/core/xx-move_on.rb +23 -0
- data/examples/core/{pulse.rb → xx-recurrent-timer.rb} +3 -2
- data/examples/core/{resource_cancel.rb → xx-resource_cancel.rb} +1 -2
- data/examples/core/{resource_delegate.rb → xx-resource_delegate.rb} +0 -0
- data/examples/core/{wait_for_signal.rb → xx-signals.rb} +0 -0
- data/examples/core/{sleep.rb → xx-sleeping.rb} +0 -0
- data/examples/core/{spin_error_backtrace.rb → xx-spin_error_backtrace.rb} +5 -2
- data/examples/core/{supervisor.rb → xx-supervisors.rb} +0 -0
- data/examples/core/{thread_cancel.rb → xx-thread_cancel.rb} +0 -0
- data/examples/core/{thread_pool.rb → xx-thread_pool.rb} +0 -0
- data/examples/core/{throttle.rb → xx-throttling.rb} +0 -0
- data/examples/core/{timeout.rb → xx-timeout.rb} +0 -0
- data/examples/core/{lock.rb → xx-using-a-mutex.rb} +0 -0
- data/examples/io/{backticks.rb → xx-backticks.rb} +0 -0
- data/examples/io/{echo_client.rb → xx-echo_client.rb} +0 -1
- data/examples/io/{echo_client_from_stdin.rb → xx-echo_client_from_stdin.rb} +0 -1
- data/examples/io/{echo_pipe.rb → xx-echo_pipe.rb} +0 -0
- data/examples/io/{echo_server.rb → xx-echo_server.rb} +0 -0
- data/examples/io/{echo_server_with_timeout.rb → xx-echo_server_with_timeout.rb} +0 -0
- data/examples/io/{echo_stdin.rb → xx-echo_stdin.rb} +0 -0
- data/examples/io/xx-httparty.rb +13 -0
- data/examples/io/{irb.rb → xx-irb.rb} +0 -0
- data/examples/io/{net-http.rb → xx-net-http.rb} +0 -0
- data/examples/io/{open.rb → xx-open.rb} +0 -1
- data/examples/io/{system.rb → xx-system.rb} +0 -0
- data/examples/io/{tcpserver.rb → xx-tcpserver.rb} +0 -0
- data/examples/io/{tcpsocket.rb → xx-tcpsocket.rb} +0 -1
- data/examples/{fs/read.rb → performance/fs_read.rb} +0 -0
- data/examples/{core → performance}/mem-usage.rb +1 -0
- data/examples/performance/multi_snooze.rb +2 -0
- data/examples/performance/snooze.rb +2 -0
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +5 -3
- data/examples/performance/thread-vs-fiber/threaded_server.rb +1 -1
- data/examples/{io/httparty_multi.rb → performance/thread-vs-fiber/xx-httparty_multi.rb} +16 -13
- data/examples/{io/httparty_threaded.rb → performance/thread-vs-fiber/xx-httparty_threaded.rb} +2 -2
- data/examples/performance/thread.rb +27 -0
- data/examples/{core → performance}/thread_pool_perf.rb +0 -0
- data/ext/gyro/extconf.rb +1 -0
- data/lib/polyphony/extensions/core.rb +0 -5
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +3 -9
- metadata +59 -167
- data/bin/poly +0 -11
- data/examples/core/cancel.rb +0 -13
- data/examples/core/enumerator.rb +0 -15
- data/examples/core/error_bubbling.rb +0 -35
- data/examples/core/fiber_error.rb +0 -9
- data/examples/core/fiber_error_with_backtrace.rb +0 -73
- data/examples/core/move_on.rb +0 -11
- data/examples/core/move_on_twice.rb +0 -16
- data/examples/core/move_on_with_ensure.rb +0 -13
- data/examples/core/move_on_with_value.rb +0 -14
- data/examples/core/multiple_spin.rb +0 -18
- data/examples/core/nested_cancel.rb +0 -40
- data/examples/core/nested_multiple_spin.rb +0 -20
- data/examples/core/nested_spin.rb +0 -19
- data/examples/core/pingpong.rb +0 -21
- data/examples/core/resource.rb +0 -30
- data/examples/core/sleep_spin.rb +0 -21
- data/examples/core/snooze.rb +0 -32
- data/examples/core/spin_error.rb +0 -17
- data/examples/core/spin_uncaught_error.rb +0 -16
- data/examples/core/supervisor_with_cancel_scope.rb +0 -23
- data/examples/core/supervisor_with_error.rb +0 -24
- data/examples/core/supervisor_with_manual_move_on.rb +0 -23
- data/examples/core/suspend.rb +0 -13
- data/examples/core/thread.rb +0 -27
- data/examples/http/config.ru +0 -7
- data/examples/http/cuba.ru +0 -22
- data/examples/http/happy_eyeballs.rb +0 -37
- data/examples/http/http2_raw.rb +0 -135
- data/examples/http/http_client.rb +0 -28
- data/examples/http/http_get.rb +0 -33
- data/examples/http/http_parse_experiment.rb +0 -123
- data/examples/http/http_proxy.rb +0 -83
- data/examples/http/http_server.js +0 -24
- data/examples/http/http_server.rb +0 -28
- data/examples/http/http_server_forked.rb +0 -29
- data/examples/http/http_server_graceful.rb +0 -27
- data/examples/http/http_server_simple.rb +0 -11
- data/examples/http/http_server_throttled.rb +0 -15
- data/examples/http/http_ws_server.rb +0 -37
- data/examples/http/https_raw_client.rb +0 -12
- data/examples/http/https_server.rb +0 -22
- data/examples/http/https_wss_server.rb +0 -39
- data/examples/http/rack_server.rb +0 -12
- data/examples/http/rack_server_https.rb +0 -19
- data/examples/http/rack_server_https_forked.rb +0 -27
- data/examples/http/websocket_secure_server.rb +0 -27
- data/examples/http/websocket_server.rb +0 -24
- data/examples/http/ws_page.html +0 -34
- data/examples/http/wss_page.html +0 -34
- data/examples/io/cat.rb +0 -12
- data/examples/io/httparty.rb +0 -10
- data/examples/io/io_read.rb +0 -9
- data/lib/ev_ext.bundle +0 -0
- data/lib/polyphony/http.rb +0 -16
- data/lib/polyphony/http/client/agent.rb +0 -131
- data/lib/polyphony/http/client/http1.rb +0 -129
- data/lib/polyphony/http/client/http2.rb +0 -180
- data/lib/polyphony/http/client/response.rb +0 -32
- data/lib/polyphony/http/client/site_connection_manager.rb +0 -109
- data/lib/polyphony/http/server.rb +0 -49
- data/lib/polyphony/http/server/http1.rb +0 -268
- data/lib/polyphony/http/server/http2.rb +0 -78
- data/lib/polyphony/http/server/http2_stream.rb +0 -136
- data/lib/polyphony/http/server/rack.rb +0 -64
- data/lib/polyphony/http/server/request.rb +0 -118
- data/lib/polyphony/websocket.rb +0 -59
- data/test/test_http_server.rb +0 -313
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a8da629de739b6091367c7220fd4a69dd83d7c78eb6d8c55c67385c8ca3edb2
|
4
|
+
data.tar.gz: 351f78d8b9635b6bc2c9838d652781a66009554287cfb5486c9fe0a0748ed6d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 768ed2703dd01653e5c71c2d17799b0c42fd9eb03f382dd3e4d3e4a337f7055d7a68643f479160febd3aa9412a9b66ccf0adf79f1608882ef0d61b625c8f7ed2
|
7
|
+
data.tar.gz: eab163c7ce680640def7fe6971359969202e6cb53238e8006c479e158c9b488bf73a2e575008a94cee1320fcf6899276da85df33d2fb00f97fa8133ad8fc3f06
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
polyphony (0.
|
5
|
-
|
6
|
-
http_parser.rb (= 0.6.0)
|
7
|
-
modulation (~> 0.25)
|
8
|
-
rack
|
4
|
+
polyphony (0.24)
|
5
|
+
modulation (~> 1.0)
|
9
6
|
|
10
7
|
GEM
|
11
8
|
remote: https://rubygems.org/
|
@@ -14,7 +11,6 @@ GEM
|
|
14
11
|
builder (3.2.4)
|
15
12
|
docile (1.3.2)
|
16
13
|
hiredis (0.6.3)
|
17
|
-
http-2 (0.10.0)
|
18
14
|
http_parser.rb (0.6.0)
|
19
15
|
httparty (0.17.0)
|
20
16
|
mime-types (~> 3.0)
|
@@ -30,10 +26,9 @@ GEM
|
|
30
26
|
builder
|
31
27
|
minitest (>= 5.0)
|
32
28
|
ruby-progressbar
|
33
|
-
modulation (0
|
29
|
+
modulation (1.0)
|
34
30
|
multi_xml (0.6.0)
|
35
31
|
pg (1.1.3)
|
36
|
-
rack (2.0.8)
|
37
32
|
rake (13.0.1)
|
38
33
|
rake-compiler (1.0.5)
|
39
34
|
rake
|
@@ -44,13 +39,13 @@ GEM
|
|
44
39
|
json (>= 1.8, < 3)
|
45
40
|
simplecov-html (~> 0.10.0)
|
46
41
|
simplecov-html (0.10.2)
|
47
|
-
websocket (1.2.8)
|
48
42
|
|
49
43
|
PLATFORMS
|
50
44
|
ruby
|
51
45
|
|
52
46
|
DEPENDENCIES
|
53
47
|
hiredis (= 0.6.3)
|
48
|
+
http_parser.rb (~> 0.6.0)
|
54
49
|
httparty (= 0.17.0)
|
55
50
|
localhost (= 1.1.4)
|
56
51
|
minitest (= 5.11.3)
|
@@ -60,7 +55,6 @@ DEPENDENCIES
|
|
60
55
|
rake-compiler (= 1.0.5)
|
61
56
|
redis (= 4.1.0)
|
62
57
|
simplecov (= 0.17.1)
|
63
|
-
websocket (= 1.2.8)
|
64
58
|
|
65
59
|
BUNDLED WITH
|
66
60
|
2.1.3
|
data/README.md
CHANGED
@@ -13,9 +13,6 @@ Polyphony makes it possible to use normal Ruby built-in classes like `IO`, and `
|
|
13
13
|
|
14
14
|
## Features
|
15
15
|
|
16
|
-
* **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server
|
17
|
-
with TLS/SSL termination, automatic ALPN protocol selection, and body
|
18
|
-
streaming**.
|
19
16
|
* Co-operative scheduling of concurrent tasks using Ruby fibers.
|
20
17
|
* High-performance event reactor for handling I/O events and timers.
|
21
18
|
* Natural, sequential programming style that makes it easy to reason about
|
@@ -25,7 +22,6 @@ Polyphony makes it possible to use normal Ruby built-in classes like `IO`, and `
|
|
25
22
|
* Code can use native networking classes and libraries, growing support for
|
26
23
|
third-party gems such as `pg` and `redis`.
|
27
24
|
* Use stdlib classes such as `TCPServer`, `TCPSocket` and
|
28
|
-
* HTTP 1 / HTTP 2 client agent with persistent connections.
|
29
25
|
* Competitive performance and scalability characteristics, in terms of both
|
30
26
|
throughput and memory consumption.
|
31
27
|
|
data/TODO.md
CHANGED
@@ -1,54 +1,8 @@
|
|
1
|
-
|
1
|
+
## 0.25 Move Other interface code into separate gem
|
2
2
|
|
3
|
-
The concurrency model and the fact that we want to serve the response object on
|
4
|
-
receiving headers and let the user lazily read the response body, means we'll
|
5
|
-
need to change the API to accept a block:
|
6
|
-
|
7
|
-
```ruby
|
8
|
-
# current API
|
9
|
-
resp = Agent.get('http://acme.org')
|
10
|
-
puts resp.body
|
11
|
-
|
12
|
-
# proposed API
|
13
|
-
Agent.get('http://acme.org') do |resp|
|
14
|
-
puts resp.body
|
15
|
-
end
|
16
|
-
```
|
17
|
-
|
18
|
-
While the block is running, the connection adapter is acquired. Once the block
|
19
|
-
is done running, the request (and response) can be discarded. The problem with
|
20
|
-
that if we spin up a coprocess from that block we risk all kinds of race
|
21
|
-
conditions and weird behaviours.
|
22
|
-
|
23
|
-
A compromise might be to allow the two: doing a `get` without providing a block
|
24
|
-
will return a response object that already has the body (i.e. the entire
|
25
|
-
response has already been received). Doing a `get` with a block will invoke the
|
26
|
-
block once headers are received, letting the user's code stream the body:
|
27
|
-
|
28
|
-
```ruby
|
29
|
-
def request(ctx, &block)
|
30
|
-
...
|
31
|
-
connection_manager.acquire do |adapter|
|
32
|
-
response = adapter.request(ctx)
|
33
|
-
if block
|
34
|
-
block.(response)
|
35
|
-
else
|
36
|
-
# wait for body
|
37
|
-
response.body
|
38
|
-
end
|
39
|
-
response
|
40
|
-
end
|
41
|
-
end
|
42
|
-
```
|
43
|
-
|
44
|
-
# Roadmap:
|
45
|
-
|
46
|
-
## 0.24 Move HTTP code into separate gem
|
47
|
-
|
48
|
-
- Pull out HTTP/websocket code, put into new `polyphony-http` gem
|
49
3
|
- Pull out redis/postgres code, put into new `polyphony-contrib` gem
|
50
4
|
|
51
|
-
## 0.
|
5
|
+
## 0.26 Full Rack adapter implementation
|
52
6
|
|
53
7
|
- Work better mechanism supervising multiple coprocesses (`when_done` feels a
|
54
8
|
bit hacky)
|
@@ -56,21 +10,16 @@ end
|
|
56
10
|
- Homogenize HTTP 1 and HTTP 2 headers - upcase ? downcase ?
|
57
11
|
- find some demo Rack apps and test with Polyphony
|
58
12
|
|
59
|
-
## 0.
|
13
|
+
## 0.27 Working Sinatra application
|
60
14
|
|
61
15
|
- app with database access (postgresql)
|
62
16
|
- benchmarks!
|
63
17
|
|
64
|
-
## 0.
|
18
|
+
## 0.28 Support for multi-threading
|
65
19
|
|
66
20
|
- Separate event loop for each thread
|
67
21
|
|
68
|
-
## 0.
|
69
|
-
|
70
|
-
- test thread / thread_pool modules
|
71
|
-
- report test coverage
|
72
|
-
|
73
|
-
## 0.29 Documentation
|
22
|
+
## 0.29 Testing && Docs
|
74
23
|
|
75
24
|
## 0.30 Integration
|
76
25
|
|
data/docs/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Polyphony - Easy Concurrency for Ruby
|
2
2
|
|
3
|
-
> Polyphony \| pəˈlɪf\(ə\)ni \|
|
4
|
-
|
5
|
-
|
3
|
+
> Polyphony \| pəˈlɪf\(ə\)ni \|
|
4
|
+
> 1. _Music_ the style of simultaneously combining a number of parts, each forming an individual melody and harmonizing with each other.
|
5
|
+
> 2. _Programming_ a Ruby gem for concurrent programming focusing on performance and developer happiness.
|
6
6
|
|
7
7
|
Polyphony is a library for building concurrent applications in Ruby. Polyphony harnesses the power of [Ruby fibers](https://ruby-doc.org/core-2.5.1/Fiber.html) to provide a cooperative, sequential coprocess-based concurrency model. Under the hood, Polyphony uses [libev](https://github.com/enki/libev) as a high-performance event reactor that provides timers, I/O watchers and other asynchronous event primitives.
|
8
8
|
|
@@ -10,14 +10,12 @@ Polyphony makes it possible to use normal Ruby built-in classes like `IO`, and `
|
|
10
10
|
|
11
11
|
## Features
|
12
12
|
|
13
|
-
* **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server with TLS/SSL termination, automatic ALPN protocol selection, and body streaming**.
|
14
13
|
* Co-operative scheduling of concurrent tasks using Ruby fibers.
|
15
14
|
* High-performance event reactor for handling I/O events and timers.
|
16
15
|
* Natural, sequential programming style that makes it easy to reason about concurrent code.
|
17
16
|
* Abstractions and constructs for controlling the execution of concurrent code: coprocesses, supervisors, cancel scopes, throttling, resource pools etc.
|
18
17
|
* Code can use native networking classes and libraries, growing support for third-party gems such as `pg` and `redis`.
|
19
18
|
* Use stdlib classes such as `TCPServer` and `TCPSocket` and `Net::HTTP`.
|
20
|
-
* HTTP 1 / HTTP 2 client agent with persistent connections.
|
21
19
|
* Competitive performance and scalability characteristics, in terms of both throughput and memory consumption.
|
22
20
|
|
23
21
|
## Prior Art
|
@@ -35,5 +33,4 @@ To learn more about using Polyphony to build concurrent applications, read the t
|
|
35
33
|
|
36
34
|
## Contributing to Polyphony
|
37
35
|
|
38
|
-
|
39
|
-
|
36
|
+
Issues and pull requests will be gladly accepted. Please use the git repository at https://github.com/digital-fabric/polyphony as your primary point of departure for contributing.
|
File without changes
|
File without changes
|
@@ -65,14 +65,14 @@ module Map
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
map_server = GenServer.start(Map, foo: :bar)
|
68
|
+
map_server = GenServer.start(Map, {foo: :bar})
|
69
69
|
|
70
70
|
puts 'getting value from map server'
|
71
71
|
v = map_server.get(:foo)
|
72
72
|
puts "value: #{v.inspect}"
|
73
73
|
|
74
74
|
puts 'putting value in map server'
|
75
|
-
map_server.put!(:foo,
|
75
|
+
map_server.put!(:foo, :baz)
|
76
76
|
|
77
77
|
puts 'getting value from map server'
|
78
78
|
v = map_server.get(:foo)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
Exception.__disable_sanitized_backtrace__ = true
|
6
|
+
|
7
|
+
puts 'going to sleep...'
|
8
|
+
move_on_after(1) do
|
9
|
+
sleep 60
|
10
|
+
puts 'woke up'
|
11
|
+
end
|
12
|
+
|
13
|
+
puts 'going to sleep...'
|
14
|
+
move_on_after(0.5) do
|
15
|
+
t0 = Time.now
|
16
|
+
sleep(60)
|
17
|
+
ensure
|
18
|
+
puts 'woke up'
|
19
|
+
end
|
20
|
+
|
21
|
+
puts 'going to sleep...'
|
22
|
+
value = move_on_after(1, with_value: :bar) { sleep 60 }
|
23
|
+
puts "got value #{value.inspect}"
|
@@ -5,7 +5,7 @@ require 'polyphony'
|
|
5
5
|
|
6
6
|
resource_count = 0
|
7
7
|
Pool = Polyphony::ResourcePool.new(limit: 3) do
|
8
|
-
|
8
|
+
+"resource#{resource_count += 1}"
|
9
9
|
end
|
10
10
|
|
11
11
|
def user(number)
|
@@ -13,7 +13,6 @@ def user(number)
|
|
13
13
|
Polyphony::CancelScope.new(timeout: 0.2) do |scope|
|
14
14
|
scope.on_cancel { puts "#{number} (cancelled)" }
|
15
15
|
Pool.acquire do |r|
|
16
|
-
scope.disable
|
17
16
|
puts "#{number} #{r.inspect} >"
|
18
17
|
sleep(0.1 + rand * 0.2)
|
19
18
|
puts "#{number} #{r.inspect} <"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
require 'httparty'
|
6
|
+
|
7
|
+
timer = spin { throttled_loop(100) {
|
8
|
+
STDOUT << '.'
|
9
|
+
} }
|
10
|
+
|
11
|
+
res = HTTParty.get('http://worldtimeapi.org/api/timezone/Europe/Paris')
|
12
|
+
puts res
|
13
|
+
timer.stop
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -18,7 +18,7 @@ class Http::Parser
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
def handle_client(socket)
|
22
22
|
parser = Http::Parser.new
|
23
23
|
req = nil
|
24
24
|
parser.on_message_complete = proc do |env|
|
@@ -47,12 +47,12 @@ def handle_request(client, parser)
|
|
47
47
|
end
|
48
48
|
|
49
49
|
spin do
|
50
|
-
server = TCPServer.open(1234)
|
50
|
+
server = TCPServer.open('0.0.0.0', 1234)
|
51
51
|
puts "listening on port 1234"
|
52
52
|
|
53
53
|
loop do
|
54
54
|
client = server.accept
|
55
|
-
|
55
|
+
spin { handle_client(client) }
|
56
56
|
end
|
57
57
|
rescue Exception => e
|
58
58
|
puts "uncaught exception: #{e.inspect}"
|
@@ -60,3 +60,5 @@ rescue Exception => e
|
|
60
60
|
exit!
|
61
61
|
server.close
|
62
62
|
end
|
63
|
+
|
64
|
+
suspend
|