tp2 0.19.3 → 0.19.4
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 +1 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -6
- data/examples/simple.rb +13 -3
- data/lib/tp2/connection.rb +7 -5
- data/lib/tp2/server.rb +30 -21
- data/lib/tp2/version.rb +1 -1
- data/test/test_server.rb +4 -6
- data/tp2.gemspec +1 -1
- 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: 9e014b48f0e569963bc4a7c69735b7d3b2745e0300285be727e56a822302705d
|
|
4
|
+
data.tar.gz: 8a620cba8ce06490c6b4c4fd830ab2883b65a41a133aa86cf0f3c382610c0c1b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03b13bf4d0529187cf96f862aa0bae5698e72337e39a2c820e319342dac8f9d8994f86bd66da2e9637947f330cac0c86ce0bec1fee299d92cc3430281231b3fc
|
|
7
|
+
data.tar.gz: 23c1881fc7db29bd5b78325a1fc7338674acb8a9db5b7cd735f0ea77e904e667312c6c49acf61b919743bdad1e375a4e519b9f517f4144b24347ab9c25d50356
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
source 'https://
|
|
1
|
+
source 'https://gem.coop'
|
|
2
2
|
|
|
3
3
|
gemspec name: 'tp2'
|
|
4
4
|
|
|
5
5
|
group :development do
|
|
6
|
-
gem 'listen', '3.
|
|
7
|
-
gem 'minitest', '
|
|
8
|
-
gem 'rake', '13.
|
|
9
|
-
gem 'rake-compiler', '1.
|
|
6
|
+
gem 'listen', '3.10.0'
|
|
7
|
+
gem 'minitest', '6.0.1'
|
|
8
|
+
gem 'rake', '13.3.1'
|
|
9
|
+
gem 'rake-compiler', '1.3.1'
|
|
10
10
|
gem 'simplecov', '0.22.0'
|
|
11
|
-
gem 'yard', '0.9.
|
|
11
|
+
gem 'yard', '0.9.38'
|
|
12
12
|
end
|
data/examples/simple.rb
CHANGED
|
@@ -8,9 +8,19 @@ end
|
|
|
8
8
|
|
|
9
9
|
require 'tp2'
|
|
10
10
|
|
|
11
|
+
BODY = 'foobar' * 1000
|
|
11
12
|
app = ->(req) {
|
|
12
|
-
req.respond(
|
|
13
|
+
req.respond(BODY)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
PORT = 1234
|
|
17
|
+
|
|
18
|
+
machine = UM.new
|
|
19
|
+
opts = {
|
|
20
|
+
banner: TP2::BANNER,
|
|
21
|
+
}
|
|
22
|
+
# opts[:logger] = TP2::Logger.new(machine, **opts)
|
|
23
|
+
env = { bind: "127.0.0.1:#{PORT}" }.merge(opts)
|
|
24
|
+
puts "Listening on #{env[:bind]}"
|
|
25
|
+
server = TP2::Server.new(machine, env) { app&.call(it) }
|
|
26
|
+
server.run
|
data/lib/tp2/connection.rb
CHANGED
|
@@ -153,6 +153,11 @@ module TP2
|
|
|
153
153
|
|
|
154
154
|
SEND_FLAGS = UM::MSG_NOSIGNAL | UM::MSG_WAITALL
|
|
155
155
|
|
|
156
|
+
EMPTY_CHUNK = "0\r\n\r\n"
|
|
157
|
+
EMPTY_CHUNK_LEN = EMPTY_CHUNK.bytesize
|
|
158
|
+
|
|
159
|
+
CHUNKED_ENCODING_POSTLUDE = "\r\n#{EMPTY_CHUNK}"
|
|
160
|
+
|
|
156
161
|
# Sends response including headers and body. Waits for the request to complete
|
|
157
162
|
# if not yet completed. The body is sent using chunked transfer encoding.
|
|
158
163
|
# @param request [Qeweney::Request] HTTP request
|
|
@@ -165,8 +170,8 @@ module TP2
|
|
|
165
170
|
@response_headers = headers
|
|
166
171
|
request&.tx_incr(formatted_headers.bytesize + (body ? body.bytesize : 0))
|
|
167
172
|
if body
|
|
168
|
-
|
|
169
|
-
@machine.
|
|
173
|
+
chunk_prelude = "#{body.bytesize.to_s(16)}\r\n"
|
|
174
|
+
@machine.sendv(@fd, formatted_headers, chunk_prelude, body, CHUNKED_ENCODING_POSTLUDE)
|
|
170
175
|
else
|
|
171
176
|
@machine.send(@fd, formatted_headers, formatted_headers.bytesize, SEND_FLAGS)
|
|
172
177
|
end
|
|
@@ -187,9 +192,6 @@ module TP2
|
|
|
187
192
|
@response_headers = headers
|
|
188
193
|
end
|
|
189
194
|
|
|
190
|
-
EMPTY_CHUNK = "0\r\n\r\n"
|
|
191
|
-
EMPTY_CHUNK_LEN = EMPTY_CHUNK.bytesize
|
|
192
|
-
|
|
193
195
|
# Sends a response body chunk. If no headers were sent, default headers are
|
|
194
196
|
# sent using #send_headers. if the done option is true(thy), an empty chunk
|
|
195
197
|
# will be sent to signal response completion to the client.
|
data/lib/tp2/server.rb
CHANGED
|
@@ -50,11 +50,15 @@ module TP2
|
|
|
50
50
|
|
|
51
51
|
def run
|
|
52
52
|
setup
|
|
53
|
-
@machine.
|
|
53
|
+
@machine.await_fibers(@accept_fibers)
|
|
54
54
|
rescue UM::Terminate
|
|
55
55
|
graceful_shutdown
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
def stop!
|
|
59
|
+
graceful_shutdown
|
|
60
|
+
end
|
|
61
|
+
|
|
58
62
|
private
|
|
59
63
|
|
|
60
64
|
def setup
|
|
@@ -69,7 +73,7 @@ module TP2
|
|
|
69
73
|
setup_server_extensions
|
|
70
74
|
|
|
71
75
|
# map fibers
|
|
72
|
-
@
|
|
76
|
+
@connection_fibers = Set.new
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
def get_bind_entries
|
|
@@ -124,47 +128,52 @@ module TP2
|
|
|
124
128
|
end
|
|
125
129
|
|
|
126
130
|
def accept_incoming(listen_fd)
|
|
127
|
-
@machine.accept_each(listen_fd)
|
|
128
|
-
conn = Connection.new(self, @machine, fd, @env, &@app)
|
|
129
|
-
f = @machine.spin(conn) do
|
|
130
|
-
it.run
|
|
131
|
-
ensure
|
|
132
|
-
@connection_fiber_map.delete(f)
|
|
133
|
-
end
|
|
134
|
-
@connection_fiber_map[f] = true
|
|
135
|
-
end
|
|
131
|
+
@machine.accept_each(listen_fd) { start_client_connection(it) }
|
|
136
132
|
rescue UM::Terminate
|
|
137
133
|
# terminated
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def start_client_connection(fd)
|
|
137
|
+
conn = Connection.new(self, @machine, fd, @env, &@app)
|
|
138
|
+
f = @machine.spin(conn) do
|
|
139
|
+
it.run
|
|
140
|
+
ensure
|
|
141
|
+
@connection_fibers.delete(f)
|
|
142
|
+
end
|
|
143
|
+
@connection_fibers << f
|
|
142
144
|
end
|
|
143
145
|
|
|
144
146
|
def close_all_server_fds
|
|
145
147
|
@server_fds.each { @machine.close_async(it) }
|
|
146
148
|
end
|
|
147
149
|
|
|
150
|
+
STOP = UM::Terminate.new
|
|
151
|
+
|
|
152
|
+
def stop_accept_fibers
|
|
153
|
+
@accept_fibers.each { @machine.schedule(it, STOP) if !it.done? }
|
|
154
|
+
@machine.await_fibers(@accept_fibers)
|
|
155
|
+
end
|
|
156
|
+
|
|
148
157
|
def graceful_shutdown
|
|
149
158
|
@env[:logger]&.info(message: 'Shutting down gracefully...')
|
|
150
159
|
|
|
151
160
|
# stop listening
|
|
152
161
|
close_all_server_fds
|
|
162
|
+
stop_accept_fibers
|
|
153
163
|
@machine.snooze
|
|
154
164
|
|
|
155
|
-
return if @
|
|
165
|
+
return if @connection_fibers.empty?
|
|
156
166
|
|
|
157
167
|
# sleep for a bit, let requests finish
|
|
158
168
|
@machine.sleep(PENDING_REQUESTS_GRACE_PERIOD)
|
|
159
|
-
return if @
|
|
169
|
+
return if @connection_fibers.empty?
|
|
160
170
|
|
|
161
171
|
# terminate pending fibers
|
|
162
|
-
pending = @
|
|
163
|
-
|
|
164
|
-
pending.each { @machine.schedule(it, signal) }
|
|
172
|
+
pending = @connection_fibers.to_a
|
|
173
|
+
pending.each { @machine.schedule(it, STOP) }
|
|
165
174
|
|
|
166
175
|
@machine.timeout(PENDING_REQUESTS_TIMEOUT_PERIOD, UM::Terminate) do
|
|
167
|
-
@machine.
|
|
176
|
+
@machine.await_fibers(@connection_fibers)
|
|
168
177
|
rescue UM::Terminate
|
|
169
178
|
# timeout on waiting for adapters to finish running, do nothing
|
|
170
179
|
end
|
data/lib/tp2/version.rb
CHANGED
data/test/test_server.rb
CHANGED
|
@@ -38,15 +38,13 @@ class ServerTest < Minitest::Test
|
|
|
38
38
|
|
|
39
39
|
def run_server
|
|
40
40
|
@server.run
|
|
41
|
-
rescue STOP
|
|
42
|
-
# ignore
|
|
43
41
|
ensure
|
|
44
42
|
@server_done = true
|
|
45
43
|
end
|
|
46
44
|
|
|
47
45
|
def teardown
|
|
48
46
|
@machine.close(@client_fd) rescue nil
|
|
49
|
-
@
|
|
47
|
+
@server.stop!
|
|
50
48
|
@machine.snooze until @server_done
|
|
51
49
|
end
|
|
52
50
|
|
|
@@ -113,7 +111,7 @@ class ServerTest < Minitest::Test
|
|
|
113
111
|
write_http_request "GET /foo HTTP/1.1\r\nServer: foo.com\r\n\r\nSCHMET /bar HTTP/1.1\r\n\r\n"
|
|
114
112
|
|
|
115
113
|
@machine.sleep(0.01)
|
|
116
|
-
@
|
|
114
|
+
@server.stop!
|
|
117
115
|
@machine.snooze
|
|
118
116
|
|
|
119
117
|
response = read_client_side
|
|
@@ -282,9 +280,9 @@ class ServerTest < Minitest::Test
|
|
|
282
280
|
@env[:logger] = TestLogger.new
|
|
283
281
|
@app = ->(req) { reqs << req; req.respond('Hello, world!', {}) }
|
|
284
282
|
|
|
285
|
-
write_http_request "GET / HTTP/1.
|
|
283
|
+
write_http_request "GET / HTTP/1.1\r\n\r\n"
|
|
286
284
|
response = read_client_side
|
|
287
|
-
expected = "HTTP/1.1 200\r\
|
|
285
|
+
expected = "HTTP/1.1 200\r\nTransfer-Encoding: chunked\r\n\r\nd\r\nHello, world!\r\n0\r\n\r\n"
|
|
288
286
|
assert_equal(expected, response)
|
|
289
287
|
|
|
290
288
|
entries = @env[:logger].entries
|
data/tp2.gemspec
CHANGED
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
|
20
20
|
s.required_ruby_version = '>= 3.4'
|
|
21
21
|
s.executables = ['tp2']
|
|
22
22
|
|
|
23
|
-
s.add_dependency 'uringmachine', '~> 0.
|
|
23
|
+
s.add_dependency 'uringmachine', '~> 0.23.1'
|
|
24
24
|
s.add_dependency 'qeweney', '~> 0.23'
|
|
25
25
|
s.add_dependency 'rack', '~> 3.1.15'
|
|
26
26
|
end
|
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.19.
|
|
4
|
+
version: 0.19.4
|
|
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.23.1
|
|
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.23.1
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: qeweney
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
111
111
|
- !ruby/object:Gem::Version
|
|
112
112
|
version: '0'
|
|
113
113
|
requirements: []
|
|
114
|
-
rubygems_version: 4.0.
|
|
114
|
+
rubygems_version: 4.0.3
|
|
115
115
|
specification_version: 4
|
|
116
116
|
summary: Experimental HTTP/1 server for UringMachine
|
|
117
117
|
test_files: []
|