tp2 0.4 → 0.5
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 +8 -0
- data/Gemfile.lock +3 -3
- data/examples/simple.rb +11 -4
- data/lib/tp2/http1_adapter.rb +3 -1
- data/lib/tp2/server.rb +46 -3
- data/lib/tp2/version.rb +1 -1
- data/test/test_server.rb +20 -0
- data/tp2.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9c8c52c6ec2e5db6393b54f0ccf96010c9c626984ea943075f1675a078e9eae
|
4
|
+
data.tar.gz: 80cf94801b882350e72d50b21e9e004c544d239e3a05e04e99db4543e88deb73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48484025b54dc3a7ea959c795ed6575d62eae1165f97ed5171343616af84da1fce9cc2e818f7e3fb540dab146b6f0bd8e1a076fba6050e03cb78cfd479615449
|
7
|
+
data.tar.gz: a3a65e353b9a5f4c1d4d3af7a4a6977f77ed7c38a1c10eb85c4a4afbbc6cc4a4c8e244be482c66b9e1ce6c61b52ffd0755959e3dff545d87b310011598baec9a
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tp2 (0.
|
4
|
+
tp2 (0.5)
|
5
5
|
qeweney (= 0.21)
|
6
|
-
uringmachine (= 0.
|
6
|
+
uringmachine (= 0.8)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
simplecov_json_formatter (~> 0.1)
|
37
37
|
simplecov-html (0.13.1)
|
38
38
|
simplecov_json_formatter (0.1.4)
|
39
|
-
uringmachine (0.
|
39
|
+
uringmachine (0.8)
|
40
40
|
yard (0.9.37)
|
41
41
|
|
42
42
|
PLATFORMS
|
data/examples/simple.rb
CHANGED
@@ -16,12 +16,19 @@ machine = UM.new
|
|
16
16
|
server = TP2::Server.new(machine, '0.0.0.0', 1234, &app)
|
17
17
|
puts "Listening on port 1234..."
|
18
18
|
|
19
|
-
machine.spin { server.run }
|
19
|
+
server_fiber = machine.spin { server.run }
|
20
20
|
|
21
|
-
|
22
|
-
trap('SIGINT') { machine.
|
21
|
+
sig_queue = UM::Queue.new
|
22
|
+
trap('SIGINT') { machine.push(sig_queue, :SIGINT) }
|
23
23
|
|
24
24
|
puts "Running... (pid: #{Process.pid})"
|
25
25
|
STDOUT.flush
|
26
|
-
|
26
|
+
|
27
|
+
# wait for signal
|
28
|
+
sig = machine.shift(sig_queue)
|
29
|
+
|
30
|
+
puts "Got signal (#{sig}), shutting down gracefully..."
|
31
|
+
machine.schedule(server_fiber, UM::Terminate.new)
|
32
|
+
machine.join(server_fiber)
|
33
|
+
|
27
34
|
puts
|
data/lib/tp2/http1_adapter.rb
CHANGED
data/lib/tp2/server.rb
CHANGED
@@ -5,6 +5,9 @@ require 'tp2/request_extensions'
|
|
5
5
|
|
6
6
|
module TP2
|
7
7
|
class Server
|
8
|
+
PENDING_REQUESTS_GRACE_PERIOD = 0.1
|
9
|
+
PENDING_REQUESTS_TIMEOUT_PERIOD = 5
|
10
|
+
|
8
11
|
def initialize(machine, hostname, port, &app)
|
9
12
|
@machine = machine
|
10
13
|
@hostname = hostname
|
@@ -12,21 +15,61 @@ module TP2
|
|
12
15
|
@app = app
|
13
16
|
end
|
14
17
|
|
18
|
+
def run
|
19
|
+
setup
|
20
|
+
accept_incoming
|
21
|
+
rescue UM::Terminate
|
22
|
+
graceful_shutdown
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
15
27
|
def setup
|
16
28
|
@server_fd = @machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
17
29
|
@machine.setsockopt(@server_fd, UM::SOL_SOCKET, UM::SO_REUSEADDR, true)
|
18
30
|
@machine.bind(@server_fd, @hostname, @port)
|
19
31
|
@machine.listen(@server_fd, UM::SOMAXCONN)
|
20
32
|
|
33
|
+
# map fibers
|
34
|
+
@fiber_map = {}
|
35
|
+
|
21
36
|
# puts "Listening on #{@hostname}:#{@port}"
|
22
37
|
end
|
23
38
|
|
24
|
-
def
|
25
|
-
setup
|
39
|
+
def accept_incoming
|
26
40
|
@machine.accept_each(@server_fd) do |fd|
|
27
41
|
conn = HTTP1Adapter.new(@machine, fd, &@app)
|
28
|
-
@machine.spin(conn)
|
42
|
+
f = @machine.spin(conn) do
|
43
|
+
it.run
|
44
|
+
ensure
|
45
|
+
@fiber_map.delete(f)
|
46
|
+
end
|
47
|
+
@fiber_map[f] = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def graceful_shutdown
|
52
|
+
# stop listening
|
53
|
+
@machine.close(@server_fd)
|
54
|
+
|
55
|
+
return if @fiber_map.empty?
|
56
|
+
|
57
|
+
# sleep for a bit, let requests finish
|
58
|
+
@machine.sleep(PENDING_REQUESTS_GRACE_PERIOD)
|
59
|
+
return if @fiber_map.empty?
|
60
|
+
|
61
|
+
# terminate pending fibers
|
62
|
+
pending = @fiber_map.keys
|
63
|
+
signal = UM::Terminate.new
|
64
|
+
pending.each { @machine.schedule(it, signal) }
|
65
|
+
|
66
|
+
@machine.timeout(PENDING_REQUESTS_TIMEOUT_PERIOD, UM::Terminate) do
|
67
|
+
@machine.join(*@fiber_map.keys)
|
68
|
+
rescue UM::Terminate
|
69
|
+
# timeout on waiting for adapters to finish running, do nothing
|
29
70
|
end
|
71
|
+
ensure
|
72
|
+
@machine.close(@server_fd)
|
30
73
|
end
|
31
74
|
end
|
32
75
|
end
|
data/lib/tp2/version.rb
CHANGED
data/test/test_server.rb
CHANGED
@@ -85,6 +85,26 @@ class ServerTest < Minitest::Test
|
|
85
85
|
assert_equal(expected, response)
|
86
86
|
end
|
87
87
|
|
88
|
+
def test_graceful_shutdown
|
89
|
+
@app = ->(req) do
|
90
|
+
@machine.sleep(1)
|
91
|
+
req.respond('Hello, world!', {})
|
92
|
+
rescue UM::Terminate
|
93
|
+
req.respond('Terminated!', {})
|
94
|
+
raise
|
95
|
+
end
|
96
|
+
|
97
|
+
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\nSCHMET /bar HTTP/1.1\r\n\r\n"
|
98
|
+
|
99
|
+
@machine.sleep(0.01)
|
100
|
+
@machine.schedule(@f_server, UM::Terminate.new)
|
101
|
+
@machine.snooze
|
102
|
+
|
103
|
+
response = read_client_side
|
104
|
+
expected = "HTTP/1.1 200\r\nContent-Length: 11\r\n\r\nTerminated!"
|
105
|
+
assert_equal(expected, response)
|
106
|
+
end
|
107
|
+
|
88
108
|
def test_pipelined_requests_with_body
|
89
109
|
skip
|
90
110
|
|
data/tp2.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tp2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '0.
|
18
|
+
version: '0.8'
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '0.
|
25
|
+
version: '0.8'
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: qeweney
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,6 +44,7 @@ extra_rdoc_files:
|
|
44
44
|
- README.md
|
45
45
|
files:
|
46
46
|
- ".gitignore"
|
47
|
+
- CHANGELOG.md
|
47
48
|
- Gemfile
|
48
49
|
- Gemfile.lock
|
49
50
|
- README.md
|