raptor 0.22.3 → 0.24.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 +46 -0
- data/Dockerfile +10 -2
- data/README.md +183 -61
- data/docs/assets/profile_picture.png +0 -0
- data/docs/assets/startup_output.svg +37 -0
- data/docs/raptor-vs-puma.md +104 -424
- data/docs/talk.md +1388 -0
- data/ext/raptor_bpf/reuseport_select.bpf.c +18 -9
- data/ext/raptor_http/extconf.rb +2 -0
- data/ext/raptor_http/raptor_http.c +165 -234
- data/ext/raptor_http2/raptor_http2.c +272 -223
- data/ext/raptor_native/raptor_native.c +38 -20
- data/lib/rackup/handler/raptor.rb +14 -12
- data/lib/raptor/binder.rb +12 -12
- data/lib/raptor/cli.rb +19 -18
- data/lib/raptor/cluster.rb +120 -74
- data/lib/raptor/control_server.rb +5 -2
- data/lib/raptor/detached_body.rb +6 -2
- data/lib/raptor/http.rb +7 -6
- data/lib/raptor/http1.rb +281 -234
- data/lib/raptor/http2.rb +356 -276
- data/lib/raptor/plugin.rb +98 -0
- data/lib/raptor/reactor.rb +138 -148
- data/lib/raptor/reuseport_bpf.rb +62 -38
- data/lib/raptor/server.rb +45 -34
- data/lib/raptor/stats.rb +15 -3
- data/lib/raptor/thread_locals.rb +4 -3
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/rackup/handler/raptor.rbs +2 -1
- data/sig/generated/raptor/binder.rbs +9 -9
- data/sig/generated/raptor/cli.rbs +6 -6
- data/sig/generated/raptor/cluster.rbs +18 -5
- data/sig/generated/raptor/control_server.rbs +2 -1
- data/sig/generated/raptor/detached_body.rbs +5 -1
- data/sig/generated/raptor/http.rbs +3 -5
- data/sig/generated/raptor/http1.rbs +119 -102
- data/sig/generated/raptor/http2.rbs +204 -190
- data/sig/generated/raptor/plugin.rbs +52 -0
- data/sig/generated/raptor/reactor.rbs +107 -118
- data/sig/generated/raptor/reuseport_bpf.rbs +54 -17
- data/sig/generated/raptor/server.rbs +26 -26
- data/sig/generated/raptor/stats.rbs +3 -2
- data/sig/generated/raptor/thread_locals.rbs +4 -3
- metadata +6 -2
- data/docs/brisrails-talk.md +0 -2398
|
@@ -4,27 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
#include "ruby.h"
|
|
6
6
|
#include "ruby/io.h"
|
|
7
|
-
#include
|
|
7
|
+
#include "ruby/thread.h"
|
|
8
8
|
#include <errno.h>
|
|
9
9
|
#include <limits.h>
|
|
10
|
+
#include <sys/uio.h>
|
|
10
11
|
|
|
11
12
|
#ifdef __linux__
|
|
12
13
|
#include <sched.h>
|
|
13
14
|
#include <sys/prctl.h>
|
|
14
|
-
#include <unistd.h>
|
|
15
15
|
#endif
|
|
16
16
|
|
|
17
17
|
static VALUE eEAGAINWaitWritable;
|
|
18
18
|
|
|
19
|
-
static VALUE
|
|
20
|
-
(void)self;
|
|
19
|
+
static VALUE vector_io_writev_nonblock(VALUE self, VALUE io, VALUE strings) {
|
|
21
20
|
Check_Type(strings, T_ARRAY);
|
|
22
21
|
long len = RARRAY_LEN(strings);
|
|
23
22
|
if (len == 0) return LONG2NUM(0);
|
|
24
23
|
if (len > IOV_MAX) len = IOV_MAX;
|
|
25
24
|
|
|
26
25
|
int fd = rb_io_descriptor(io);
|
|
27
|
-
struct iovec *iov =
|
|
26
|
+
struct iovec *iov = ALLOCA_N(struct iovec, len);
|
|
28
27
|
|
|
29
28
|
for (long i = 0; i < len; i++) {
|
|
30
29
|
VALUE str = RARRAY_AREF(strings, i);
|
|
@@ -43,8 +42,9 @@ static VALUE raptor_native_writev_nonblock(VALUE self, VALUE io, VALUE strings)
|
|
|
43
42
|
return LONG2NUM((long)written);
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// Pins the calling thread to the Nth CPU of its current affinity mask, so
|
|
46
|
+
// worker indexes map onto the CPUs the process is actually allowed to use.
|
|
47
|
+
static VALUE cpu_pin(VALUE self, VALUE cpu) {
|
|
48
48
|
#ifdef __linux__
|
|
49
49
|
int worker_index = NUM2INT(cpu);
|
|
50
50
|
cpu_set_t current;
|
|
@@ -55,7 +55,10 @@ static VALUE raptor_native_pin_to_cpu(VALUE self, VALUE cpu) {
|
|
|
55
55
|
int seen = 0;
|
|
56
56
|
for (int candidate = 0; candidate < CPU_SETSIZE; candidate++) {
|
|
57
57
|
if (!CPU_ISSET(candidate, ¤t)) continue;
|
|
58
|
-
if (seen == worker_index) {
|
|
58
|
+
if (seen == worker_index) {
|
|
59
|
+
cpu_id = candidate;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
59
62
|
seen++;
|
|
60
63
|
}
|
|
61
64
|
if (cpu_id < 0) return Qfalse;
|
|
@@ -66,13 +69,11 @@ static VALUE raptor_native_pin_to_cpu(VALUE self, VALUE cpu) {
|
|
|
66
69
|
if (sched_setaffinity(0, sizeof(set), &set) < 0) rb_sys_fail("sched_setaffinity");
|
|
67
70
|
return Qtrue;
|
|
68
71
|
#else
|
|
69
|
-
(void)cpu;
|
|
70
72
|
return Qfalse;
|
|
71
73
|
#endif
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
static VALUE
|
|
75
|
-
(void)self;
|
|
76
|
+
static VALUE cpu_count(VALUE self) {
|
|
76
77
|
#ifdef __linux__
|
|
77
78
|
cpu_set_t set;
|
|
78
79
|
CPU_ZERO(&set);
|
|
@@ -83,8 +84,24 @@ static VALUE raptor_native_cpu_count(VALUE self) {
|
|
|
83
84
|
#endif
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
#ifdef __linux__
|
|
88
|
+
static void *cpu_yield_without_gvl(void *unused) {
|
|
89
|
+
sched_yield();
|
|
90
|
+
return NULL;
|
|
91
|
+
}
|
|
92
|
+
#endif
|
|
93
|
+
|
|
94
|
+
// Thread.pass cannot yield to native threads that have not rejoined
|
|
95
|
+
// Ruby's ready queue.
|
|
96
|
+
static VALUE cpu_yield(VALUE self) {
|
|
97
|
+
rb_thread_schedule();
|
|
98
|
+
#ifdef __linux__
|
|
99
|
+
rb_thread_call_without_gvl(cpu_yield_without_gvl, NULL, NULL, NULL);
|
|
100
|
+
#endif
|
|
101
|
+
return Qnil;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static VALUE subreaper_enable(VALUE self) {
|
|
88
105
|
#if defined(__linux__) && defined(PR_SET_CHILD_SUBREAPER)
|
|
89
106
|
if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) rb_sys_fail("prctl");
|
|
90
107
|
return Qtrue;
|
|
@@ -96,18 +113,19 @@ static VALUE raptor_native_enable_subreaper(VALUE self) {
|
|
|
96
113
|
RUBY_FUNC_EXPORTED void Init_raptor_native(void) {
|
|
97
114
|
rb_ext_ractor_safe(true);
|
|
98
115
|
|
|
116
|
+
rb_global_variable(&eEAGAINWaitWritable);
|
|
117
|
+
eEAGAINWaitWritable = rb_const_get(rb_cIO, rb_intern("EAGAINWaitWritable"));
|
|
118
|
+
|
|
99
119
|
VALUE mRaptor = rb_define_module("Raptor");
|
|
100
120
|
|
|
101
121
|
VALUE mVectorIO = rb_define_module_under(mRaptor, "VectorIO");
|
|
102
|
-
rb_define_singleton_method(mVectorIO, "writev_nonblock",
|
|
122
|
+
rb_define_singleton_method(mVectorIO, "writev_nonblock", vector_io_writev_nonblock, 2);
|
|
103
123
|
|
|
104
124
|
VALUE mCPU = rb_define_module_under(mRaptor, "CPU");
|
|
105
|
-
rb_define_singleton_method(mCPU, "pin",
|
|
106
|
-
rb_define_singleton_method(mCPU, "count",
|
|
125
|
+
rb_define_singleton_method(mCPU, "pin", cpu_pin, 1);
|
|
126
|
+
rb_define_singleton_method(mCPU, "count", cpu_count, 0);
|
|
127
|
+
rb_define_singleton_method(mCPU, "yield", cpu_yield, 0);
|
|
107
128
|
|
|
108
129
|
VALUE mSubreaper = rb_define_module_under(mRaptor, "Subreaper");
|
|
109
|
-
rb_define_singleton_method(mSubreaper, "enable",
|
|
110
|
-
|
|
111
|
-
eEAGAINWaitWritable = rb_const_get(rb_cIO, rb_intern("EAGAINWaitWritable"));
|
|
112
|
-
rb_global_variable(&eEAGAINWaitWritable);
|
|
130
|
+
rb_define_singleton_method(mSubreaper, "enable", subreaper_enable, 0);
|
|
113
131
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# rbs_inline: enabled
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require "concurrent/utility/processor_counter"
|
|
5
|
-
|
|
6
4
|
module Rackup
|
|
7
5
|
module Handler
|
|
8
6
|
# Rack handler for booting Raptor through Rackup, `rails server`, or any
|
|
@@ -18,7 +16,8 @@ module Rackup
|
|
|
18
16
|
#
|
|
19
17
|
# @param app [#call] the Rack application to serve
|
|
20
18
|
# @param options [Hash] handler options provided by Rackup or the host
|
|
21
|
-
# @yield
|
|
19
|
+
# @yield before the cluster starts running
|
|
20
|
+
# @yieldparam cluster [::Raptor::Cluster] the cluster instance
|
|
22
21
|
# @return [void]
|
|
23
22
|
#
|
|
24
23
|
# @rbs (^(Hash[String, untyped]) -> [Integer, Hash[String, String | Array[String]], untyped] app, **untyped options) { (::Raptor::Cluster) -> void } -> void
|
|
@@ -62,7 +61,7 @@ module Rackup
|
|
|
62
61
|
def self.build_cluster_options(app, options)
|
|
63
62
|
defaults = DEFAULT_OPTIONS.dup
|
|
64
63
|
|
|
65
|
-
if user_supplied_options = options.delete(:user_supplied_options)
|
|
64
|
+
if (user_supplied_options = options.delete(:user_supplied_options))
|
|
66
65
|
(options.keys - user_supplied_options).each do |key|
|
|
67
66
|
defaults[key] = options.delete(key)
|
|
68
67
|
end
|
|
@@ -71,7 +70,9 @@ module Rackup
|
|
|
71
70
|
cli_defaults = ::Raptor::CLI::DEFAULT_OPTIONS
|
|
72
71
|
config_path = options[:Config] || ::Raptor::CLI.default_config_path
|
|
73
72
|
config = config_path ? ::Raptor::CLI.load_config_file(config_path) : {}
|
|
74
|
-
|
|
73
|
+
environment_workers = Integer(ENV["RAPTOR_WORKERS"], 10) if ENV["RAPTOR_WORKERS"]
|
|
74
|
+
environment_threads = Integer(ENV["RAPTOR_THREADS"], 10) if ENV["RAPTOR_THREADS"]
|
|
75
|
+
threads = (options[:Threads] || environment_threads || config[:threads] || cli_defaults[:threads]).to_i
|
|
75
76
|
max_threads = options[:MaxThreads] || ENV["RAPTOR_MAX_THREADS"] || config.fetch(:max_threads, cli_defaults[:max_threads])
|
|
76
77
|
|
|
77
78
|
result = {
|
|
@@ -81,13 +82,13 @@ module Rackup
|
|
|
81
82
|
config[:binds] || ["tcp://#{defaults[:Host]}:#{defaults[:Port]}"]
|
|
82
83
|
end,
|
|
83
84
|
socket_backlog: (config[:socket_backlog] || cli_defaults[:socket_backlog]).to_i,
|
|
84
|
-
drain_accept_queue: config.
|
|
85
|
-
workers: (options[:Workers] ||
|
|
85
|
+
drain_accept_queue: config.fetch(:drain_accept_queue, cli_defaults[:drain_accept_queue]),
|
|
86
|
+
workers: (options[:Workers] || environment_workers || config[:workers] || cli_defaults[:workers]).to_i,
|
|
86
87
|
threads: threads,
|
|
87
88
|
max_threads: ::Raptor::CLI.parse_max_threads(max_threads, threads: threads),
|
|
88
|
-
cpu_affinity: config.
|
|
89
|
-
clean_thread_locals: config.
|
|
90
|
-
clean_fiber_locals: config.
|
|
89
|
+
cpu_affinity: config.fetch(:cpu_affinity, cli_defaults[:cpu_affinity]),
|
|
90
|
+
clean_thread_locals: config.fetch(:clean_thread_locals, cli_defaults[:clean_thread_locals]),
|
|
91
|
+
clean_fiber_locals: config.fetch(:clean_fiber_locals, cli_defaults[:clean_fiber_locals]),
|
|
91
92
|
app: app
|
|
92
93
|
}
|
|
93
94
|
result[:rackup] = config[:rackup] if config.key?(:rackup)
|
|
@@ -105,14 +106,15 @@ module Rackup
|
|
|
105
106
|
result[:before_worker_boot] = config.fetch(:before_worker_boot, cli_defaults[:before_worker_boot])
|
|
106
107
|
result[:before_worker_shutdown] = config.fetch(:before_worker_shutdown, cli_defaults[:before_worker_shutdown])
|
|
107
108
|
result[:before_refork] = config.fetch(:before_refork, cli_defaults[:before_refork])
|
|
108
|
-
result[:
|
|
109
|
+
result[:plugins] = config.fetch(:plugins, cli_defaults[:plugins])
|
|
110
|
+
result[:stats_file] = config.fetch(:stats_file, cli_defaults[:stats_file])
|
|
109
111
|
result[:control_url] = config[:control_url] if config.key?(:control_url)
|
|
110
112
|
result[:pid_file] = config[:pid_file] if config.key?(:pid_file)
|
|
111
113
|
result[:stdout_file] = config[:stdout_file] if config.key?(:stdout_file)
|
|
112
114
|
result[:stderr_file] = config[:stderr_file] if config.key?(:stderr_file)
|
|
113
115
|
result[:access_log_file] = config[:access_log_file] if config.key?(:access_log_file)
|
|
114
116
|
result[:on_error] = config[:on_error] if config.key?(:on_error)
|
|
115
|
-
result
|
|
117
|
+
config.merge(result)
|
|
116
118
|
end
|
|
117
119
|
private_class_method :build_cluster_options
|
|
118
120
|
end
|
data/lib/raptor/binder.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# rbs_inline: enabled
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "openssl"
|
|
4
5
|
require "socket"
|
|
5
6
|
require "uri"
|
|
6
7
|
|
|
@@ -56,17 +57,17 @@ module Raptor
|
|
|
56
57
|
# Returns the array of bind URIs.
|
|
57
58
|
#
|
|
58
59
|
# @return [Array<String>]
|
|
59
|
-
attr_reader :bind_uris
|
|
60
|
+
attr_reader :bind_uris #: Array[String]
|
|
60
61
|
|
|
61
62
|
# Returns the kernel `listen()` queue depth for TCP/SSL listeners.
|
|
62
63
|
#
|
|
63
64
|
# @return [Integer]
|
|
64
|
-
attr_reader :socket_backlog
|
|
65
|
+
attr_reader :socket_backlog #: Integer
|
|
65
66
|
|
|
66
67
|
# Returns the array of listening sockets.
|
|
67
68
|
#
|
|
68
69
|
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
69
|
-
attr_reader :listeners
|
|
70
|
+
attr_reader :listeners #: Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
70
71
|
|
|
71
72
|
# Creates a new Binder and binds each URI. `localhost` expands to both
|
|
72
73
|
# IPv4 and IPv6 loopback; when `inherited_fds` supplies file descriptors
|
|
@@ -113,8 +114,8 @@ module Raptor
|
|
|
113
114
|
end
|
|
114
115
|
end
|
|
115
116
|
|
|
116
|
-
# Returns the port of the first TCP
|
|
117
|
-
# is configured.
|
|
117
|
+
# Returns the port of the first TCP, SSL, or cleartext HTTP/2 listener,
|
|
118
|
+
# or 0 when none is configured.
|
|
118
119
|
#
|
|
119
120
|
# @return [Integer]
|
|
120
121
|
#
|
|
@@ -185,7 +186,7 @@ module Raptor
|
|
|
185
186
|
|
|
186
187
|
# Creates fresh listeners for the given URI.
|
|
187
188
|
#
|
|
188
|
-
# @param uri [URI] the parsed bind URI
|
|
189
|
+
# @param uri [URI::Generic] the parsed bind URI
|
|
189
190
|
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
190
191
|
# @raise [UnknownBindSchemeError] if the URI scheme is not supported
|
|
191
192
|
#
|
|
@@ -208,7 +209,7 @@ module Raptor
|
|
|
208
209
|
# Reconstructs listeners for the given URI from inherited file
|
|
209
210
|
# descriptors.
|
|
210
211
|
#
|
|
211
|
-
# @param uri [URI] the parsed bind URI the FDs were bound to
|
|
212
|
+
# @param uri [URI::Generic] the parsed bind URI the FDs were bound to
|
|
212
213
|
# @param filenos [Array<Integer>] file descriptors to wrap
|
|
213
214
|
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
214
215
|
# @raise [UnknownBindSchemeError] if the URI scheme is not supported
|
|
@@ -240,7 +241,7 @@ module Raptor
|
|
|
240
241
|
# @rbs (String? host, Integer? port) -> Array[TCPServer]
|
|
241
242
|
def create_tcp_listeners(host, port)
|
|
242
243
|
if host == "localhost"
|
|
243
|
-
return loopback_addresses.
|
|
244
|
+
return loopback_addresses.flat_map { |address| create_tcp_listeners(address, port) }
|
|
244
245
|
end
|
|
245
246
|
|
|
246
247
|
host = host[1..-2] if host&.start_with?("[")
|
|
@@ -250,6 +251,7 @@ module Raptor
|
|
|
250
251
|
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
|
251
252
|
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true) if Socket.const_defined?(:SO_REUSEPORT)
|
|
252
253
|
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
254
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_DEFER_ACCEPT, 1) if Socket.const_defined?(:TCP_DEFER_ACCEPT)
|
|
253
255
|
socket.bind(addrinfo)
|
|
254
256
|
socket.listen(@socket_backlog)
|
|
255
257
|
|
|
@@ -299,7 +301,7 @@ module Raptor
|
|
|
299
301
|
#
|
|
300
302
|
# @param host [String, nil] hostname or IP address to bind to
|
|
301
303
|
# @param port [Integer, nil] port number to bind to
|
|
302
|
-
# @param ssl_params [Hash
|
|
304
|
+
# @param ssl_params [Hash{String => String}] SSL options (`cert` and `key` file paths)
|
|
303
305
|
# @return [Array<SslListener>] array containing the created SSL listener(s)
|
|
304
306
|
#
|
|
305
307
|
# @rbs (String? host, Integer? port, Hash[String, String] ssl_params) -> Array[SslListener]
|
|
@@ -312,13 +314,11 @@ module Raptor
|
|
|
312
314
|
# Builds a frozen `OpenSSL::SSL::SSLContext` configured for HTTP/2 and
|
|
313
315
|
# HTTP/1.1 ALPN negotiation.
|
|
314
316
|
#
|
|
315
|
-
# @param ssl_params [Hash
|
|
317
|
+
# @param ssl_params [Hash{String => String}] SSL options (`cert` and `key` file paths)
|
|
316
318
|
# @return [OpenSSL::SSL::SSLContext]
|
|
317
319
|
#
|
|
318
320
|
# @rbs (Hash[String, String] ssl_params) -> OpenSSL::SSL::SSLContext
|
|
319
321
|
def build_ssl_context(ssl_params)
|
|
320
|
-
require "openssl"
|
|
321
|
-
|
|
322
322
|
OpenSSL::SSL::SSLContext.new.tap do |ssl_context|
|
|
323
323
|
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(ssl_params["cert"]))
|
|
324
324
|
ssl_context.key = OpenSSL::PKey.read(File.read(ssl_params["key"]))
|
data/lib/raptor/cli.rb
CHANGED
|
@@ -7,6 +7,7 @@ require "optparse"
|
|
|
7
7
|
require "concurrent/utility/processor_counter"
|
|
8
8
|
|
|
9
9
|
require_relative "cluster"
|
|
10
|
+
require_relative "version"
|
|
10
11
|
|
|
11
12
|
module Raptor
|
|
12
13
|
# Command-line interface for the Raptor web server.
|
|
@@ -48,18 +49,18 @@ module Raptor
|
|
|
48
49
|
write_timeout: 5,
|
|
49
50
|
max_body_size: nil,
|
|
50
51
|
body_spool_threshold: 1024 * 1024
|
|
51
|
-
},
|
|
52
|
+
}.freeze,
|
|
52
53
|
http1: {
|
|
53
54
|
ractors: nil,
|
|
54
55
|
persistent_data_timeout: 65,
|
|
55
56
|
max_keepalive_requests: 1000
|
|
56
|
-
},
|
|
57
|
+
}.freeze,
|
|
57
58
|
http2: {
|
|
58
59
|
ractors: nil,
|
|
59
60
|
max_concurrent_streams: 100,
|
|
60
61
|
keepalive_interval: 10,
|
|
61
62
|
keepalive_timeout: 5
|
|
62
|
-
},
|
|
63
|
+
}.freeze,
|
|
63
64
|
worker_boot_timeout: 60,
|
|
64
65
|
worker_timeout: 60,
|
|
65
66
|
worker_drain_timeout: 25,
|
|
@@ -69,12 +70,13 @@ module Raptor
|
|
|
69
70
|
before_worker_boot: [].freeze,
|
|
70
71
|
before_worker_shutdown: [].freeze,
|
|
71
72
|
before_refork: [].freeze,
|
|
73
|
+
plugins: [].freeze,
|
|
72
74
|
stats_file: "tmp/raptor.json",
|
|
73
75
|
control_url: nil,
|
|
74
76
|
pid_file: nil,
|
|
75
77
|
stdout_file: nil,
|
|
76
78
|
stderr_file: nil,
|
|
77
|
-
access_log_file: nil
|
|
79
|
+
access_log_file: nil
|
|
78
80
|
}.freeze
|
|
79
81
|
|
|
80
82
|
DEFAULT_CONFIG_PATHS = ["raptor.rb", "config/raptor.rb"].freeze
|
|
@@ -131,17 +133,17 @@ module Raptor
|
|
|
131
133
|
max_threads
|
|
132
134
|
end
|
|
133
135
|
|
|
134
|
-
# @rbs @command: Symbol
|
|
135
136
|
# @rbs @options: Hash[Symbol, untyped]
|
|
137
|
+
# @rbs @command: Symbol
|
|
136
138
|
# @rbs @parser: OptionParser
|
|
137
139
|
|
|
138
|
-
# Creates a new CLI
|
|
139
|
-
#
|
|
140
|
-
# flag.
|
|
140
|
+
# Creates a new CLI from `argv`. A rackup file may be given as the
|
|
141
|
+
# first positional argument; every other value is parsed as a flag.
|
|
141
142
|
#
|
|
142
143
|
# @param argv [Array<String>] command-line arguments to parse
|
|
143
144
|
# @return [void]
|
|
144
145
|
# @raise [OptionParser::ParseError] if invalid options are provided
|
|
146
|
+
# @raise [ArgumentError] if the config file or max threads value is invalid
|
|
145
147
|
#
|
|
146
148
|
# @rbs (Array[String] argv) -> void
|
|
147
149
|
def initialize(argv)
|
|
@@ -203,7 +205,7 @@ module Raptor
|
|
|
203
205
|
end
|
|
204
206
|
end
|
|
205
207
|
|
|
206
|
-
# Returns the path from a `-c`/`--config` flag in `argv`,
|
|
208
|
+
# Returns the path from a `-c`/`--config` flag in `argv`, recognizing
|
|
207
209
|
# all four OptionParser-accepted forms (`-c PATH`, `-cPATH`,
|
|
208
210
|
# `--config PATH`, `--config=PATH`).
|
|
209
211
|
#
|
|
@@ -258,6 +260,8 @@ module Raptor
|
|
|
258
260
|
#
|
|
259
261
|
# @rbs () -> OptionParser
|
|
260
262
|
def create_parser
|
|
263
|
+
cli_binds = []
|
|
264
|
+
|
|
261
265
|
OptionParser.new do |opts|
|
|
262
266
|
opts.banner = "Usage: raptor [options] [rackup file]"
|
|
263
267
|
|
|
@@ -266,11 +270,8 @@ module Raptor
|
|
|
266
270
|
end
|
|
267
271
|
|
|
268
272
|
opts.on("-b", "--bind URI", String, "Bind address (default: tcp://0.0.0.0:9292)") do |bind|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
else
|
|
272
|
-
@options[:binds] << bind
|
|
273
|
-
end
|
|
273
|
+
cli_binds << bind
|
|
274
|
+
@options[:binds] = cli_binds
|
|
274
275
|
end
|
|
275
276
|
|
|
276
277
|
opts.on("--socket-backlog NUM", Integer, "Socket listen backlog (default: 1024)") do |num|
|
|
@@ -333,7 +334,7 @@ module Raptor
|
|
|
333
334
|
@options[:connection][:body_spool_threshold] = bytes
|
|
334
335
|
end
|
|
335
336
|
|
|
336
|
-
opts.on("--http1-ractors NUM", Integer, "Number of HTTP/1.1 pipeline ractors per worker (default: `round(cores / workers)`, clamped to 1
|
|
337
|
+
opts.on("--http1-ractors NUM", Integer, "Number of HTTP/1.1 pipeline ractors per worker (default: `round(cores / workers)`, clamped to 1..#{Cluster::HTTP1_RACTOR_COUNT_CAP})") do |num|
|
|
337
338
|
@options[:http1][:ractors] = num
|
|
338
339
|
end
|
|
339
340
|
|
|
@@ -345,7 +346,7 @@ module Raptor
|
|
|
345
346
|
@options[:http1][:max_keepalive_requests] = num
|
|
346
347
|
end
|
|
347
348
|
|
|
348
|
-
opts.on("--http2-ractors NUM", Integer, "Number of HTTP/2 pipeline ractors per worker (default: `round(cores / workers)`, clamped to 1
|
|
349
|
+
opts.on("--http2-ractors NUM", Integer, "Number of HTTP/2 pipeline ractors per worker (default: `round(cores / workers)`, clamped to 1..#{Cluster::HTTP2_RACTOR_COUNT_CAP})") do |num|
|
|
349
350
|
@options[:http2][:ractors] = num
|
|
350
351
|
end
|
|
351
352
|
|
|
@@ -377,7 +378,7 @@ module Raptor
|
|
|
377
378
|
@options[:worker_shutdown_timeout] = timeout
|
|
378
379
|
end
|
|
379
380
|
|
|
380
|
-
opts.on("--refork-after NUM", Integer, "Refork workers from a warmed source after any worker crosses NUM requests; 0 disables (default: 1000)") do |num|
|
|
381
|
+
opts.on("--refork-after NUM", Integer, "Refork workers from a warmed source after any worker crosses NUM requests; 0 disables (default: 1000 on Linux, off elsewhere)") do |num|
|
|
381
382
|
@options[:refork_after] = num
|
|
382
383
|
end
|
|
383
384
|
|
|
@@ -411,7 +412,7 @@ module Raptor
|
|
|
411
412
|
end
|
|
412
413
|
|
|
413
414
|
opts.on("-v", "--version", "Show version") do
|
|
414
|
-
puts
|
|
415
|
+
puts VERSION
|
|
415
416
|
exit
|
|
416
417
|
end
|
|
417
418
|
end
|