raptor 0.7.0 → 0.8.0
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 +19 -0
- data/README.md +148 -23
- data/lib/rackup/handler/raptor.rb +12 -2
- data/lib/raptor/binder.rb +122 -28
- data/lib/raptor/cli.rb +82 -21
- data/lib/raptor/cluster.rb +188 -32
- data/lib/raptor/http.rb +75 -0
- data/lib/raptor/{request.rb → http1.rb} +200 -79
- data/lib/raptor/http2.rb +85 -40
- data/lib/raptor/reactor.rb +22 -15
- data/lib/raptor/server.rb +57 -37
- data/lib/raptor/stats.rb +1 -1
- data/lib/raptor/systemd.rb +69 -0
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/raptor/binder.rbs +72 -5
- data/sig/generated/raptor/cli.rbs +2 -3
- data/sig/generated/raptor/cluster.rbs +89 -13
- data/sig/generated/raptor/http.rbs +52 -0
- data/sig/generated/raptor/{request.rbs → http1.rbs} +107 -31
- data/sig/generated/raptor/http2.rbs +46 -13
- data/sig/generated/raptor/reactor.rbs +18 -11
- data/sig/generated/raptor/server.rbs +32 -18
- data/sig/generated/raptor/systemd.rbs +42 -0
- metadata +7 -3
|
@@ -17,10 +17,15 @@ module Raptor
|
|
|
17
17
|
|
|
18
18
|
@state: Atom
|
|
19
19
|
|
|
20
|
+
@write_timeout: Integer
|
|
21
|
+
|
|
20
22
|
# Creates a new Writer.
|
|
21
23
|
#
|
|
22
|
-
# @
|
|
23
|
-
|
|
24
|
+
# @param write_timeout [Integer] per-write socket timeout passed through to {Http.socket_write}
|
|
25
|
+
# @return [void]
|
|
26
|
+
#
|
|
27
|
+
# @rbs (write_timeout: Integer) -> void
|
|
28
|
+
def initialize: (write_timeout: Integer) -> void
|
|
24
29
|
|
|
25
30
|
# Writes frames to the socket, coordinating with concurrent writers
|
|
26
31
|
# so that exactly one thread is actively writing at any time.
|
|
@@ -36,7 +41,7 @@ module Raptor
|
|
|
36
41
|
# Per-connection outbound flow-control accounting.
|
|
37
42
|
#
|
|
38
43
|
# Tracks the peer's connection-level and per-stream receive windows so
|
|
39
|
-
# outbound DATA frames respect RFC 7540
|
|
44
|
+
# outbound DATA frames respect RFC 7540 section 5.2. Threads dispatching stream
|
|
40
45
|
# responses call `acquire` to reserve send capacity; threads applying
|
|
41
46
|
# inbound WINDOW_UPDATE or SETTINGS frames call the mutating methods to
|
|
42
47
|
# replenish it. The connection window and per-stream windows live in
|
|
@@ -93,7 +98,7 @@ module Raptor
|
|
|
93
98
|
def add_stream_window: (Integer stream_id, Integer increment) -> void
|
|
94
99
|
|
|
95
100
|
# Updates the peer's `SETTINGS_INITIAL_WINDOW_SIZE`. Shifts every
|
|
96
|
-
# existing stream window by the delta as required by RFC 7540
|
|
101
|
+
# existing stream window by the delta as required by RFC 7540 section 6.9.2.
|
|
97
102
|
#
|
|
98
103
|
# @param new_size [Integer] the peer's new initial window size
|
|
99
104
|
# @return [void]
|
|
@@ -140,28 +145,44 @@ module Raptor
|
|
|
140
145
|
|
|
141
146
|
HOP_BY_HOP_HEADERS: untyped
|
|
142
147
|
|
|
148
|
+
@initial_settings_frame: String
|
|
149
|
+
|
|
143
150
|
@on_error: ^(Hash[String, untyped]?, Exception) -> void | nil
|
|
144
151
|
|
|
152
|
+
@access_log_io: IO?
|
|
153
|
+
|
|
154
|
+
@write_timeout: Integer
|
|
155
|
+
|
|
145
156
|
@server_port: Integer
|
|
146
157
|
|
|
147
158
|
@app: ^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ]
|
|
148
159
|
|
|
160
|
+
# The initial server SETTINGS frame sent on every new HTTP/2 connection.
|
|
161
|
+
#
|
|
162
|
+
# @return [String] the encoded SETTINGS frame
|
|
163
|
+
attr_reader initial_settings_frame: untyped
|
|
164
|
+
|
|
149
165
|
# Creates a new Http2 handler.
|
|
150
166
|
#
|
|
151
167
|
# @param app [#call] the Rack application to dispatch requests to
|
|
152
168
|
# @param server_port [Integer] port number used to populate SERVER_PORT in the Rack env
|
|
169
|
+
# @param connection_options [Hash] per-connection settings shared across protocols
|
|
170
|
+
# @option connection_options [Integer] :write_timeout per-write socket timeout in seconds
|
|
171
|
+
# @param http2_options [Hash] HTTP/2-specific settings
|
|
172
|
+
# @option http2_options [Integer] :max_concurrent_streams maximum HTTP/2 concurrent streams per connection
|
|
173
|
+
# @param access_log_io [IO, nil] IO to write Common Log Format access entries to, or nil to disable
|
|
153
174
|
# @param on_error [#call, nil] callback invoked with (env, exception) when the Rack app raises
|
|
154
175
|
# @return [void]
|
|
155
176
|
#
|
|
156
|
-
# @rbs (^(Hash[String, untyped]) -> [Integer, Hash[String, String | Array[String]], untyped] app, Integer server_port, ?on_error: ^(Hash[String, untyped]?, Exception) -> void | nil) -> void
|
|
157
|
-
def initialize: (^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ] app, Integer server_port, ?on_error: ^(Hash[String, untyped]?, Exception) -> void | nil) -> void
|
|
177
|
+
# @rbs (^(Hash[String, untyped]) -> [Integer, Hash[String, String | Array[String]], untyped] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http2_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?on_error: ^(Hash[String, untyped]?, Exception) -> void | nil) -> void
|
|
178
|
+
def initialize: (^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http2_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?on_error: ^(Hash[String, untyped]?, Exception) -> void | nil) -> void
|
|
158
179
|
|
|
159
|
-
#
|
|
180
|
+
# Creates a per-connection {Writer} configured with the handler's write timeout.
|
|
160
181
|
#
|
|
161
|
-
# @return [
|
|
182
|
+
# @return [Writer] a new per-connection frame writer
|
|
162
183
|
#
|
|
163
|
-
# @rbs () ->
|
|
164
|
-
def
|
|
184
|
+
# @rbs () -> Writer
|
|
185
|
+
def create_writer: () -> Writer
|
|
165
186
|
|
|
166
187
|
# Processes HTTP/2 frames from the connection buffer.
|
|
167
188
|
#
|
|
@@ -271,10 +292,10 @@ module Raptor
|
|
|
271
292
|
# @param status [Integer] HTTP status code
|
|
272
293
|
# @param headers [Hash] response headers from the Rack application
|
|
273
294
|
# @param body [Object] response body responding to each
|
|
274
|
-
# @return [
|
|
295
|
+
# @return [String] the response body size in bytes
|
|
275
296
|
#
|
|
276
|
-
# @rbs (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, untyped body) ->
|
|
277
|
-
def write_http2_response: (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, untyped body) ->
|
|
297
|
+
# @rbs (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, untyped body) -> String
|
|
298
|
+
def write_http2_response: (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, untyped body) -> String
|
|
278
299
|
|
|
279
300
|
# Writes a 500 error response as HTTP/2 frames.
|
|
280
301
|
#
|
|
@@ -286,6 +307,18 @@ module Raptor
|
|
|
286
307
|
# @rbs (OpenSSL::SSL::SSLSocket socket, Writer writer, Integer stream_id) -> void
|
|
287
308
|
def write_http2_error_response: (OpenSSL::SSL::SSLSocket socket, Writer writer, Integer stream_id) -> void
|
|
288
309
|
|
|
310
|
+
# Instance-level wrapper around {Http.write_access_log} that routes to
|
|
311
|
+
# the configured `@access_log_io`.
|
|
312
|
+
#
|
|
313
|
+
# @param env [Hash] the Rack environment
|
|
314
|
+
# @param status [Integer] the response status code
|
|
315
|
+
# @param size [String] the response body size in bytes, or `-` if unknown
|
|
316
|
+
# @param remote_addr [String] the client IP address
|
|
317
|
+
# @return [void]
|
|
318
|
+
#
|
|
319
|
+
# @rbs (Hash[String, untyped] env, Integer status, String size, String remote_addr) -> void
|
|
320
|
+
def write_access_log: (Hash[String, untyped] env, Integer status, String size, String remote_addr) -> void
|
|
321
|
+
|
|
289
322
|
# Builds a Rack environment hash from HTTP/2 headers and body.
|
|
290
323
|
#
|
|
291
324
|
# Translates HTTP/2 pseudo-headers into Rack-compatible environment keys
|
|
@@ -10,10 +10,12 @@ module Raptor
|
|
|
10
10
|
# the server uses for backpressure control to prevent overload.
|
|
11
11
|
#
|
|
12
12
|
# @example
|
|
13
|
-
# reactor = Reactor.new(
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
13
|
+
# reactor = Reactor.new(
|
|
14
|
+
# ractor_pool,
|
|
15
|
+
# thread_pool,
|
|
16
|
+
# connection_options: { first_data_timeout: 30, chunk_data_timeout: 10 },
|
|
17
|
+
# http1_options: { persistent_data_timeout: 65 }
|
|
18
|
+
# )
|
|
17
19
|
# reactor.run
|
|
18
20
|
# reactor.add(id: client.object_id, socket: client)
|
|
19
21
|
# # ... later
|
|
@@ -71,7 +73,11 @@ module Raptor
|
|
|
71
73
|
|
|
72
74
|
@selector: NIO::Selector
|
|
73
75
|
|
|
74
|
-
@
|
|
76
|
+
@persistent_data_timeout: Integer
|
|
77
|
+
|
|
78
|
+
@chunk_data_timeout: Integer
|
|
79
|
+
|
|
80
|
+
@first_data_timeout: Integer
|
|
75
81
|
|
|
76
82
|
@ractor_pool: untyped
|
|
77
83
|
|
|
@@ -81,14 +87,15 @@ module Raptor
|
|
|
81
87
|
#
|
|
82
88
|
# @param ractor_pool [RactorPool] ractor pool for HTTP parsing
|
|
83
89
|
# @param thread_pool [AtomicThreadPool] thread pool for application processing
|
|
84
|
-
# @param
|
|
85
|
-
# @option
|
|
86
|
-
# @option
|
|
87
|
-
# @
|
|
90
|
+
# @param connection_options [Hash] per-connection timeout configuration
|
|
91
|
+
# @option connection_options [Integer] :first_data_timeout timeout for initial data
|
|
92
|
+
# @option connection_options [Integer] :chunk_data_timeout timeout for subsequent chunks
|
|
93
|
+
# @param http1_options [Hash] HTTP/1.1-specific configuration
|
|
94
|
+
# @option http1_options [Integer] :persistent_data_timeout timeout for keep-alive idle connections
|
|
88
95
|
# @return [void]
|
|
89
96
|
#
|
|
90
|
-
# @rbs (untyped ractor_pool, untyped thread_pool,
|
|
91
|
-
def initialize: (untyped ractor_pool, untyped thread_pool,
|
|
97
|
+
# @rbs (untyped ractor_pool, untyped thread_pool, connection_options: Hash[Symbol, untyped], http1_options: Hash[Symbol, untyped]) -> void
|
|
98
|
+
def initialize: (untyped ractor_pool, untyped thread_pool, connection_options: Hash[Symbol, untyped], http1_options: Hash[Symbol, untyped]) -> void
|
|
92
99
|
|
|
93
100
|
# Starts the reactor's main event loop in a new thread.
|
|
94
101
|
#
|
|
@@ -14,9 +14,10 @@ module Raptor
|
|
|
14
14
|
#
|
|
15
15
|
# @example
|
|
16
16
|
# binder = Binder.new(["tcp://0.0.0.0:3000"])
|
|
17
|
-
# reactor = Reactor.new(ractor_pool, thread_pool,
|
|
18
|
-
#
|
|
19
|
-
#
|
|
17
|
+
# reactor = Reactor.new(ractor_pool, thread_pool, connection_options: {}, http1_options: {})
|
|
18
|
+
# http1 = Http1.new(app, 3000)
|
|
19
|
+
# http2 = Http2.new(app, 3000)
|
|
20
|
+
# server = Server.new(binder, reactor, thread_pool, http1, http2, connection_options: { first_data_timeout: 30 })
|
|
20
21
|
# server.run
|
|
21
22
|
# # ... later
|
|
22
23
|
# server.shutdown
|
|
@@ -35,9 +36,13 @@ module Raptor
|
|
|
35
36
|
|
|
36
37
|
@running: AtomicBoolean
|
|
37
38
|
|
|
38
|
-
@
|
|
39
|
+
@drain_accept_queue: bool
|
|
39
40
|
|
|
40
|
-
@
|
|
41
|
+
@first_data_timeout: Integer
|
|
42
|
+
|
|
43
|
+
@http2: Http2
|
|
44
|
+
|
|
45
|
+
@http1: Http1
|
|
41
46
|
|
|
42
47
|
@thread_pool: AtomicThreadPool
|
|
43
48
|
|
|
@@ -50,12 +55,14 @@ module Raptor
|
|
|
50
55
|
# @param binder [Binder] the binder managing listening sockets
|
|
51
56
|
# @param reactor [Reactor] the reactor for handling client connections
|
|
52
57
|
# @param thread_pool [AtomicThreadPool] thread pool for application processing
|
|
53
|
-
# @param
|
|
54
|
-
# @param
|
|
58
|
+
# @param http1 [Http1] the HTTP/1.1 handler
|
|
59
|
+
# @param http2 [Http2] the HTTP/2 handler (provides the initial SETTINGS frame)
|
|
60
|
+
# @param connection_options [Hash] per-connection timeout configuration, used to bound TLS handshakes
|
|
61
|
+
# @param drain_accept_queue [Boolean] whether to drain the kernel accept queue on shutdown
|
|
55
62
|
# @return [void]
|
|
56
63
|
#
|
|
57
|
-
# @rbs (Binder binder, Reactor reactor, AtomicThreadPool thread_pool,
|
|
58
|
-
def initialize: (Binder binder, Reactor reactor, AtomicThreadPool thread_pool,
|
|
64
|
+
# @rbs (Binder binder, Reactor reactor, AtomicThreadPool thread_pool, Http1 http1, Http2 http2, connection_options: Hash[Symbol, untyped], ?drain_accept_queue: bool) -> void
|
|
65
|
+
def initialize: (Binder binder, Reactor reactor, AtomicThreadPool thread_pool, Http1 http1, Http2 http2, connection_options: Hash[Symbol, untyped], ?drain_accept_queue: bool) -> void
|
|
59
66
|
|
|
60
67
|
# Starts the server's main accept loop in a new thread.
|
|
61
68
|
#
|
|
@@ -71,8 +78,9 @@ module Raptor
|
|
|
71
78
|
|
|
72
79
|
# Gracefully shuts down the server.
|
|
73
80
|
#
|
|
74
|
-
# Stops accepting new connections and closes all listening sockets.
|
|
75
|
-
#
|
|
81
|
+
# Stops accepting new connections and closes all listening sockets. When
|
|
82
|
+
# `drain_accept_queue` is enabled, dispatches every connection already in
|
|
83
|
+
# the kernel accept queue before closing the listeners.
|
|
76
84
|
#
|
|
77
85
|
# @return [void]
|
|
78
86
|
#
|
|
@@ -81,6 +89,14 @@ module Raptor
|
|
|
81
89
|
|
|
82
90
|
private
|
|
83
91
|
|
|
92
|
+
# Dispatches every connection already in the kernel accept queue for each
|
|
93
|
+
# listener until all are drained.
|
|
94
|
+
#
|
|
95
|
+
# @return [void]
|
|
96
|
+
#
|
|
97
|
+
# @rbs () -> void
|
|
98
|
+
def drain_accept_queue: () -> void
|
|
99
|
+
|
|
84
100
|
# Accepts a connection from the given listener and dispatches it.
|
|
85
101
|
#
|
|
86
102
|
# For SSL listeners the TLS handshake is offloaded to the thread pool so
|
|
@@ -90,11 +106,10 @@ module Raptor
|
|
|
90
106
|
# follow the HTTP/1.1 path.
|
|
91
107
|
#
|
|
92
108
|
# @param listener [TCPServer, UNIXServer, Binder::SslListener] the ready listener
|
|
93
|
-
# @
|
|
94
|
-
# @return [void]
|
|
109
|
+
# @return [Boolean] true if a connection was accepted, false if the listener had nothing to dispatch
|
|
95
110
|
#
|
|
96
|
-
# @rbs (TCPServer | UNIXServer | Binder::SslListener listener
|
|
97
|
-
def accept_connection: (TCPServer | UNIXServer | Binder::SslListener listener
|
|
111
|
+
# @rbs (TCPServer | UNIXServer | Binder::SslListener listener) -> bool
|
|
112
|
+
def accept_connection: (TCPServer | UNIXServer | Binder::SslListener listener) -> bool
|
|
98
113
|
|
|
99
114
|
# Performs the TLS handshake for an accepted SSL connection and dispatches
|
|
100
115
|
# it through the HTTP/2 or HTTP/1.1 path. The handshake is bounded by
|
|
@@ -103,11 +118,10 @@ module Raptor
|
|
|
103
118
|
# @param listener [Binder::SslListener] the SSL listener that accepted the connection
|
|
104
119
|
# @param tcp_client [TCPSocket] the accepted TCP socket
|
|
105
120
|
# @param remote_addr [String] the client's IP address
|
|
106
|
-
# @param reactor [Reactor] the reactor to dispatch the connection to
|
|
107
121
|
# @return [void]
|
|
108
122
|
#
|
|
109
|
-
# @rbs (Binder::SslListener listener, TCPSocket tcp_client, String remote_addr
|
|
110
|
-
def dispatch_ssl_connection: (Binder::SslListener listener, TCPSocket tcp_client, String remote_addr
|
|
123
|
+
# @rbs (Binder::SslListener listener, TCPSocket tcp_client, String remote_addr) -> void
|
|
124
|
+
def dispatch_ssl_connection: (Binder::SslListener listener, TCPSocket tcp_client, String remote_addr) -> void
|
|
111
125
|
|
|
112
126
|
# Drives a non-blocking SSL handshake to completion, bounded by the
|
|
113
127
|
# configured first-data timeout. Returns true on success, false on
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated from lib/raptor/systemd.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Raptor
|
|
4
|
+
# Integration with systemd's service notification protocol and
|
|
5
|
+
# socket-activation file descriptors.
|
|
6
|
+
module Systemd
|
|
7
|
+
LISTEN_FDS_START: ::Integer
|
|
8
|
+
|
|
9
|
+
LISTEN_FDNAMES_ENV: ::String
|
|
10
|
+
|
|
11
|
+
LISTEN_FDS_ENV: ::String
|
|
12
|
+
|
|
13
|
+
LISTEN_PID_ENV: ::String
|
|
14
|
+
|
|
15
|
+
NOTIFY_SOCKET_ENV: ::String
|
|
16
|
+
|
|
17
|
+
# Sends `message` to the systemd notification socket, returning true on
|
|
18
|
+
# success and false when the socket is unset or the send fails.
|
|
19
|
+
#
|
|
20
|
+
# @param message [String] notify protocol payload, e.g. "READY=1"
|
|
21
|
+
# @return [Boolean]
|
|
22
|
+
#
|
|
23
|
+
# @rbs (String message) -> bool
|
|
24
|
+
def self.notify: (String message) -> bool
|
|
25
|
+
|
|
26
|
+
# Returns the file descriptors passed in via socket activation, or an
|
|
27
|
+
# empty array when systemd has not exported any.
|
|
28
|
+
#
|
|
29
|
+
# @return [Array<Integer>]
|
|
30
|
+
#
|
|
31
|
+
# @rbs () -> Array[Integer]
|
|
32
|
+
def self.listen_fds: () -> Array[Integer]
|
|
33
|
+
|
|
34
|
+
# Clears the socket-activation environment variables so children don't
|
|
35
|
+
# act on stale values.
|
|
36
|
+
#
|
|
37
|
+
# @return [void]
|
|
38
|
+
#
|
|
39
|
+
# @rbs () -> void
|
|
40
|
+
def self.clear_listen_env: () -> void
|
|
41
|
+
end
|
|
42
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: raptor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Young
|
|
@@ -121,24 +121,28 @@ files:
|
|
|
121
121
|
- lib/raptor/binder.rb
|
|
122
122
|
- lib/raptor/cli.rb
|
|
123
123
|
- lib/raptor/cluster.rb
|
|
124
|
+
- lib/raptor/http.rb
|
|
125
|
+
- lib/raptor/http1.rb
|
|
124
126
|
- lib/raptor/http2.rb
|
|
125
127
|
- lib/raptor/log.rb
|
|
126
128
|
- lib/raptor/reactor.rb
|
|
127
|
-
- lib/raptor/request.rb
|
|
128
129
|
- lib/raptor/server.rb
|
|
129
130
|
- lib/raptor/stats.rb
|
|
131
|
+
- lib/raptor/systemd.rb
|
|
130
132
|
- lib/raptor/version.rb
|
|
131
133
|
- sig/generated/rackup/handler/raptor.rbs
|
|
132
134
|
- sig/generated/raptor.rbs
|
|
133
135
|
- sig/generated/raptor/binder.rbs
|
|
134
136
|
- sig/generated/raptor/cli.rbs
|
|
135
137
|
- sig/generated/raptor/cluster.rbs
|
|
138
|
+
- sig/generated/raptor/http.rbs
|
|
139
|
+
- sig/generated/raptor/http1.rbs
|
|
136
140
|
- sig/generated/raptor/http2.rbs
|
|
137
141
|
- sig/generated/raptor/log.rbs
|
|
138
142
|
- sig/generated/raptor/reactor.rbs
|
|
139
|
-
- sig/generated/raptor/request.rbs
|
|
140
143
|
- sig/generated/raptor/server.rbs
|
|
141
144
|
- sig/generated/raptor/stats.rbs
|
|
145
|
+
- sig/generated/raptor/systemd.rbs
|
|
142
146
|
- sig/generated/raptor/version.rbs
|
|
143
147
|
homepage: https://github.com/joshuay03/raptor
|
|
144
148
|
licenses:
|