polyphony-http 0.27 → 0.28
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/.github/workflows/test.yml +11 -2
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +4 -4
- data/README.md +4 -0
- data/docs/README.md +38 -14
- data/examples/http_server.rb +1 -1
- data/examples/http_server_forked.rb +3 -3
- data/lib/polyphony/http/client/site_connection_manager.rb +2 -2
- data/lib/polyphony/http/server.rb +2 -0
- data/lib/polyphony/http/server/http1.rb +8 -2
- data/lib/polyphony/http/version.rb +1 -1
- data/polyphony-http.gemspec +1 -1
- data/test/helper.rb +8 -0
- data/test/test_http_server.rb +9 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 882ce6b077ffccdf3dc9cd98c85fbd49470778265f20bc6f7c2eae5e2cc097b6
|
4
|
+
data.tar.gz: fd424de4ac965624d1194c86ec2342fc8a55fee8b76bdb69875b8aa3381af601
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d039c3b8b1ffa1aae9dbf40a87d6673b9bc4309d09eab0e0bca6aba1c07e3795947cf81e4a1365d94f248f7cecda43bd9075f726bcd8e719c9e7bf52bfe25feb
|
7
|
+
data.tar.gz: 82d11593f49a3175de1284a3f98bc7a08f867fb46894e68ac4e2feafa2509fb7c824fedd63f56f1d7d559526bfbdb75f5b1b4a7b87c3a4628140c6ac8c58d761
|
data/.github/workflows/test.yml
CHANGED
@@ -4,12 +4,21 @@ on: [push]
|
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
|
-
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
os: [ubuntu-latest]
|
11
|
+
ruby: [2.6, 2.7]
|
12
|
+
|
13
|
+
name: >-
|
14
|
+
${{matrix.os}}, ${{matrix.ruby}}
|
15
|
+
|
16
|
+
runs-on: ${{matrix.os}}
|
8
17
|
steps:
|
9
18
|
- uses: actions/checkout@v1
|
10
19
|
- uses: actions/setup-ruby@v1
|
11
20
|
with:
|
12
|
-
ruby-version:
|
21
|
+
ruby-version: ${{matrix.ruby}}
|
13
22
|
- name: Install dependencies
|
14
23
|
run: |
|
15
24
|
gem install bundler
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
polyphony-http (0.
|
4
|
+
polyphony-http (0.28)
|
5
5
|
http-2 (~> 0.10.0)
|
6
6
|
http_parser.rb (~> 0.6.0)
|
7
|
-
polyphony (~> 0.
|
7
|
+
polyphony (~> 0.41)
|
8
8
|
rack (~> 2.0.8)
|
9
9
|
websocket (~> 1.2.8)
|
10
10
|
|
@@ -14,7 +14,7 @@ GEM
|
|
14
14
|
ansi (1.5.0)
|
15
15
|
builder (3.2.4)
|
16
16
|
docile (1.3.2)
|
17
|
-
http-2 (0.10.
|
17
|
+
http-2 (0.10.2)
|
18
18
|
http_parser.rb (0.6.0)
|
19
19
|
json (2.1.0)
|
20
20
|
localhost (1.1.4)
|
@@ -24,7 +24,7 @@ GEM
|
|
24
24
|
builder
|
25
25
|
minitest (>= 5.0)
|
26
26
|
ruby-progressbar
|
27
|
-
polyphony (0.
|
27
|
+
polyphony (0.41)
|
28
28
|
rack (2.0.9)
|
29
29
|
rake (12.3.3)
|
30
30
|
ruby-progressbar (1.10.1)
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Polyphony - Easy Concurrency for Ruby
|
2
2
|
|
3
|
+
[](http://rubygems.org/gems/polyphony-http)
|
4
|
+
[](https://github.com/digital-fabric/polyphony-http/actions?query=workflow%3ATests)
|
5
|
+
[](https://github.com/digital-fabric/polyphony-http/blob/master/LICENSE)
|
6
|
+
|
3
7
|
[DOCS](https://dfab.gitbook.io/polyphony) |
|
4
8
|
[EXAMPLES](examples)
|
5
9
|
|
data/docs/README.md
CHANGED
@@ -1,38 +1,62 @@
|
|
1
1
|
# Polyphony - Easy Concurrency for Ruby
|
2
2
|
|
3
3
|
> Polyphony \| pəˈlɪf\(ə\)ni \|
|
4
|
-
> 1. _Music_ the style of simultaneously combining a number of parts, each
|
5
|
-
>
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
Polyphony
|
4
|
+
> 1. _Music_ the style of simultaneously combining a number of parts, each
|
5
|
+
> forming an individual melody and harmonizing with each other.
|
6
|
+
> 2. _Programming_ a Ruby gem for concurrent programming focusing on performance
|
7
|
+
> and developer happiness.
|
8
|
+
|
9
|
+
Polyphony is a library for building concurrent applications in Ruby. Polyphony
|
10
|
+
harnesses the power of [Ruby fibers](https://ruby-doc.org/core-2.5.1/Fiber.html)
|
11
|
+
to provide a cooperative, sequential coprocess-based concurrency model. Under
|
12
|
+
the hood, Polyphony uses [libev](https://github.com/enki/libev) as a
|
13
|
+
high-performance event reactor that provides timers, I/O watchers and other
|
14
|
+
asynchronous event primitives.
|
15
|
+
|
16
|
+
Polyphony makes it possible to use normal Ruby built-in classes like `IO`, and
|
17
|
+
`Socket` in a concurrent fashion without having to resort to threads. Polyphony
|
18
|
+
takes care of context-switching automatically whenever a blocking call like
|
19
|
+
`Socket#accept` or `IO#read` is issued.
|
10
20
|
|
11
21
|
## Features
|
12
22
|
|
13
|
-
* **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server
|
23
|
+
* **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server
|
24
|
+
with TLS/SSL termination, automatic ALPN protocol selection, and body
|
25
|
+
streaming**.
|
14
26
|
* Co-operative scheduling of concurrent tasks using Ruby fibers.
|
15
27
|
* High-performance event reactor for handling I/O events and timers.
|
16
28
|
* Natural, sequential programming style that makes it easy to reason about concurrent code.
|
17
|
-
* Abstractions and constructs for controlling the execution of concurrent code:
|
18
|
-
|
29
|
+
* Abstractions and constructs for controlling the execution of concurrent code:
|
30
|
+
coprocesses, supervisors, throttling, resource pools etc.
|
31
|
+
* Code can use native networking classes and libraries, growing support for
|
32
|
+
third-party gems such as `pg` and `redis`.
|
19
33
|
* Use stdlib classes such as `TCPServer` and `TCPSocket` and `Net::HTTP`.
|
20
34
|
* HTTP 1 / HTTP 2 client agent with persistent connections.
|
21
|
-
* Competitive performance and scalability characteristics, in terms of both
|
35
|
+
* Competitive performance and scalability characteristics, in terms of both
|
36
|
+
throughput and memory consumption.
|
22
37
|
|
23
38
|
## Prior Art
|
24
39
|
|
25
40
|
Polyphony draws inspiration from the following, in no particular order:
|
26
41
|
|
27
|
-
* [nio4r](https://github.com/socketry/nio4r/) and
|
42
|
+
* [nio4r](https://github.com/socketry/nio4r/) and
|
43
|
+
[async](https://github.com/socketry/async) (Polyphony's C-extension code is
|
44
|
+
largely a spinoff of
|
45
|
+
[nio4r's](https://github.com/socketry/nio4r/tree/master/ext))
|
28
46
|
* [EventMachine](https://github.com/eventmachine/eventmachine)
|
29
47
|
* [Trio](https://trio.readthedocs.io/)
|
30
|
-
* [Erlang supervisors](http://erlang.org/doc/man/supervisor.html) (and actually,
|
48
|
+
* [Erlang supervisors](http://erlang.org/doc/man/supervisor.html) (and actually,
|
49
|
+
Erlang in general)
|
31
50
|
|
32
51
|
## Going further
|
33
52
|
|
34
|
-
To learn more about using Polyphony to build concurrent applications, read the
|
53
|
+
To learn more about using Polyphony to build concurrent applications, read the
|
54
|
+
technical overview below, or look at the [included
|
55
|
+
examples](https://github.com/digital-fabric/polyphony/tree/9e0f3b09213156bdf376ef33684ef267517f06e8/examples/README.md).
|
56
|
+
A thorough reference is forthcoming.
|
35
57
|
|
36
58
|
## Contributing to Polyphony
|
37
59
|
|
38
|
-
Issues and pull requests will be gladly accepted. Please use the git repository
|
60
|
+
Issues and pull requests will be gladly accepted. Please use the git repository
|
61
|
+
at https://github.com/digital-fabric/polyphony as your primary point of
|
62
|
+
departure for contributing.
|
data/examples/http_server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
|
-
require 'polyphony/http'
|
4
|
+
require 'polyphony/http/server'
|
5
5
|
|
6
6
|
::Exception.__disable_sanitized_backtrace__ = true
|
7
7
|
|
@@ -15,7 +15,7 @@ server = Polyphony::HTTP::Server.listen('0.0.0.0', 1234, opts)
|
|
15
15
|
puts 'Listening on port 1234'
|
16
16
|
|
17
17
|
child_pids = []
|
18
|
-
|
18
|
+
8.times do
|
19
19
|
pid = Polyphony.fork do
|
20
20
|
puts "forked pid: #{Process.pid}"
|
21
21
|
server.each do |req|
|
@@ -26,4 +26,4 @@ child_pids = []
|
|
26
26
|
child_pids << pid
|
27
27
|
end
|
28
28
|
|
29
|
-
child_pids.each { |pid|
|
29
|
+
child_pids.each { |pid| Thread.current.agent.waitpid(pid) }
|
@@ -18,11 +18,11 @@ class SiteConnectionManager < ResourcePool
|
|
18
18
|
# end
|
19
19
|
|
20
20
|
def acquire
|
21
|
-
|
21
|
+
Thread.current.agent.ref
|
22
22
|
prepare_first_connection if @size.zero?
|
23
23
|
super
|
24
24
|
ensure
|
25
|
-
|
25
|
+
Thread.current.agent.unref
|
26
26
|
# The size goes back to 0 only in case existing connections get into an
|
27
27
|
# error state and then get discarded
|
28
28
|
@state = nil if @size == 0
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'polyphony'
|
3
4
|
require_relative './server/http1'
|
4
5
|
require_relative './server/http2'
|
5
6
|
|
@@ -31,6 +32,7 @@ module Polyphony
|
|
31
32
|
loop do
|
32
33
|
client = server.accept
|
33
34
|
spin { client_loop(client, opts, &handler) }
|
35
|
+
snooze
|
34
36
|
rescue OpenSSL::SSL::SSLError
|
35
37
|
# disregard
|
36
38
|
end
|
@@ -17,8 +17,11 @@ module Polyphony
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def each(&block)
|
20
|
-
|
20
|
+
loop do
|
21
|
+
data = @conn.readpartial(8192)
|
21
22
|
return if handle_incoming_data(data, &block)
|
23
|
+
rescue EOFError
|
24
|
+
break
|
22
25
|
end
|
23
26
|
rescue SystemCallError, IOError
|
24
27
|
# ignore
|
@@ -68,11 +71,14 @@ module Polyphony
|
|
68
71
|
# callback
|
69
72
|
def consume_request
|
70
73
|
request = @requests_head
|
71
|
-
|
74
|
+
loop do
|
75
|
+
data = @conn.readpartial(8192)
|
72
76
|
@parser << data
|
73
77
|
return if request.complete?
|
74
78
|
|
75
79
|
snooze
|
80
|
+
rescue EOFError
|
81
|
+
break
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
data/polyphony-http.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.executables = ['poly']
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'polyphony', '~>0.
|
22
|
+
s.add_runtime_dependency 'polyphony', '~>0.42'
|
23
23
|
|
24
24
|
s.add_runtime_dependency 'http_parser.rb', '~>0.6.0'
|
25
25
|
s.add_runtime_dependency 'http-2', '~>0.10.0'
|
data/test/helper.rb
CHANGED
@@ -20,17 +20,25 @@ Minitest::Reporters.use! [
|
|
20
20
|
|
21
21
|
class MiniTest::Test
|
22
22
|
def setup
|
23
|
+
# puts "* setup #{self.name}"
|
23
24
|
if Fiber.current.children.size > 0
|
24
25
|
puts "Children left: #{Fiber.current.children.inspect}"
|
25
26
|
exit!
|
26
27
|
end
|
27
28
|
Fiber.current.setup_main_fiber
|
29
|
+
Fiber.current.instance_variable_set(:@auto_watcher, nil)
|
30
|
+
Thread.current.agent = Polyphony::LibevAgent.new
|
28
31
|
sleep 0
|
29
32
|
end
|
30
33
|
|
31
34
|
def teardown
|
35
|
+
# puts "* teardown #{self.name.inspect} Fiber.current: #{Fiber.current.inspect}"
|
32
36
|
Fiber.current.terminate_all_children
|
33
37
|
Fiber.current.await_all_children
|
38
|
+
rescue => e
|
39
|
+
puts e
|
40
|
+
puts e.backtrace.join("\n")
|
41
|
+
exit!
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
data/test/test_http_server.rb
CHANGED
@@ -208,6 +208,7 @@ class HTTP1ServerTest < MiniTest::Test
|
|
208
208
|
opts = {
|
209
209
|
upgrade: {
|
210
210
|
echo: lambda do |conn, _headers|
|
211
|
+
p :echo1
|
211
212
|
conn << <<~HTTP.http_lines
|
212
213
|
HTTP/1.1 101 Switching Protocols
|
213
214
|
Upgrade: echo
|
@@ -215,9 +216,12 @@ class HTTP1ServerTest < MiniTest::Test
|
|
215
216
|
|
216
217
|
HTTP
|
217
218
|
|
218
|
-
|
219
|
+
loop do
|
220
|
+
data = conn.readpartial(8192)
|
219
221
|
conn << data
|
220
222
|
snooze
|
223
|
+
rescue EOFError
|
224
|
+
break
|
221
225
|
end
|
222
226
|
done = true
|
223
227
|
end
|
@@ -270,12 +274,13 @@ class HTTP1ServerTest < MiniTest::Test
|
|
270
274
|
|
271
275
|
connection.close
|
272
276
|
assert !done
|
277
|
+
|
273
278
|
10.times { snooze }
|
274
279
|
assert done
|
275
280
|
end
|
276
281
|
|
277
282
|
def test_big_download
|
278
|
-
chunk_size =
|
283
|
+
chunk_size = 1000
|
279
284
|
chunk_count = 1000
|
280
285
|
chunk = '*' * chunk_size
|
281
286
|
@server, connection = spin_server do |req|
|
@@ -292,7 +297,8 @@ class HTTP1ServerTest < MiniTest::Test
|
|
292
297
|
count = 0
|
293
298
|
|
294
299
|
connection << "GET / HTTP/1.1\r\n\r\n"
|
295
|
-
|
300
|
+
|
301
|
+
while (data = connection.read(chunk_size))
|
296
302
|
response << data
|
297
303
|
count += 1
|
298
304
|
snooze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.28'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: polyphony
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.42'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.42'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: http_parser.rb
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|