raptor 0.11.0 → 0.13.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/.buildkite/pipeline.yml +100 -0
- data/CHANGELOG.md +11 -0
- data/README.md +47 -31
- data/docs/raptor-vs-puma.md +81 -63
- data/ext/raptor_bpf/reuseport_select.bpf.c +8 -3
- data/ext/raptor_native/raptor_native.c +16 -2
- data/lib/raptor/binder.rb +37 -87
- data/lib/raptor/cli.rb +18 -25
- data/lib/raptor/cluster.rb +385 -82
- data/lib/raptor/http.rb +18 -0
- data/lib/raptor/http1.rb +244 -233
- data/lib/raptor/http2.rb +42 -63
- data/lib/raptor/reactor.rb +21 -52
- data/lib/raptor/reuseport_bpf.rb +27 -5
- data/lib/raptor/server.rb +24 -42
- data/lib/raptor/stats.rb +3 -8
- data/lib/raptor/systemd.rb +1 -1
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/raptor/binder.rbs +34 -80
- data/sig/generated/raptor/cli.rbs +9 -25
- data/sig/generated/raptor/cluster.rbs +183 -85
- data/sig/generated/raptor/http.rbs +10 -0
- data/sig/generated/raptor/http1.rbs +129 -113
- data/sig/generated/raptor/http2.rbs +31 -48
- data/sig/generated/raptor/reactor.rbs +21 -52
- data/sig/generated/raptor/reuseport_bpf.rbs +20 -2
- data/sig/generated/raptor/server.rbs +19 -39
- data/sig/generated/raptor/stats.rbs +3 -8
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7a531c4a4d9cfe93de0c4e8d255d9eac6a09d59f9af6d3884231cd0a383aca5
|
|
4
|
+
data.tar.gz: 3155fd5b27d53b5a65a9be9cc36d139da801ad3ce33a188ea9a46c77289ee97e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 53bfe180b9db4a6d9f7fdb3ea2f11bf2f19b5fa81c54beb09e74caa189381a52587756c6acae9b18ce16a5500a278a0b737934bc9b5e129fe3002605ee2ac5c1
|
|
7
|
+
data.tar.gz: a235a90619e1a8c1935208d1c516280bf911335e075bc6e91d5be78d134c5cc385381dba899328ebc2f8da213753d31618f5328e5eec8d609a06cfb1c30b5cb8
|
data/.buildkite/pipeline.yml
CHANGED
|
@@ -18,6 +18,25 @@ steps:
|
|
|
18
18
|
- bundle install
|
|
19
19
|
- bundle exec rake ci
|
|
20
20
|
|
|
21
|
+
- label: ":ruby: Ruby 4.0 +GC.stress"
|
|
22
|
+
image: "ruby:4.0"
|
|
23
|
+
env:
|
|
24
|
+
RUBY_GC_STRESS: "1"
|
|
25
|
+
commands:
|
|
26
|
+
- ruby -v
|
|
27
|
+
- bundle install
|
|
28
|
+
- bundle exec rake ci
|
|
29
|
+
|
|
30
|
+
- label: ":ruby: Ruby 4.0 +YJIT +GC.stress"
|
|
31
|
+
image: "ruby:4.0"
|
|
32
|
+
env:
|
|
33
|
+
RUBY_YJIT_ENABLE: "1"
|
|
34
|
+
RUBY_GC_STRESS: "1"
|
|
35
|
+
commands:
|
|
36
|
+
- ruby -v
|
|
37
|
+
- bundle install
|
|
38
|
+
- bundle exec rake ci
|
|
39
|
+
|
|
21
40
|
- label: ":ruby: Ruby head"
|
|
22
41
|
soft_fail: true
|
|
23
42
|
image: "rubylang/ruby:master-dev"
|
|
@@ -38,6 +57,29 @@ steps:
|
|
|
38
57
|
- bundle install
|
|
39
58
|
- bundle exec rake ci
|
|
40
59
|
|
|
60
|
+
- label: ":ruby: Ruby head +GC.stress"
|
|
61
|
+
soft_fail: true
|
|
62
|
+
image: "rubylang/ruby:master-dev"
|
|
63
|
+
env:
|
|
64
|
+
RUBY_GC_STRESS: "1"
|
|
65
|
+
commands:
|
|
66
|
+
- apt-get update && apt-get install -y libyaml-dev
|
|
67
|
+
- ruby -v
|
|
68
|
+
- bundle install
|
|
69
|
+
- bundle exec rake ci
|
|
70
|
+
|
|
71
|
+
- label: ":ruby: Ruby head +YJIT +GC.stress"
|
|
72
|
+
soft_fail: true
|
|
73
|
+
image: "rubylang/ruby:master-dev"
|
|
74
|
+
env:
|
|
75
|
+
RUBY_YJIT_ENABLE: "1"
|
|
76
|
+
RUBY_GC_STRESS: "1"
|
|
77
|
+
commands:
|
|
78
|
+
- apt-get update && apt-get install -y libyaml-dev
|
|
79
|
+
- ruby -v
|
|
80
|
+
- bundle install
|
|
81
|
+
- bundle exec rake ci
|
|
82
|
+
|
|
41
83
|
- group: ":mac: macOS"
|
|
42
84
|
key: macos
|
|
43
85
|
steps:
|
|
@@ -65,6 +107,33 @@ steps:
|
|
|
65
107
|
- bundle install
|
|
66
108
|
- bundle exec rake ci
|
|
67
109
|
|
|
110
|
+
- label: ":ruby: Ruby 4.0 +GC.stress"
|
|
111
|
+
agents:
|
|
112
|
+
queue: macos
|
|
113
|
+
env:
|
|
114
|
+
RUBY_GC_STRESS: "1"
|
|
115
|
+
commands:
|
|
116
|
+
- brew install --quiet ruby@4.0
|
|
117
|
+
- export PATH="$(brew --prefix ruby@4.0)/bin:$PATH"
|
|
118
|
+
- bundle config set --local path .bundle
|
|
119
|
+
- ruby -v
|
|
120
|
+
- bundle install
|
|
121
|
+
- bundle exec rake ci
|
|
122
|
+
|
|
123
|
+
- label: ":ruby: Ruby 4.0 +YJIT +GC.stress"
|
|
124
|
+
agents:
|
|
125
|
+
queue: macos
|
|
126
|
+
env:
|
|
127
|
+
RUBY_YJIT_ENABLE: "1"
|
|
128
|
+
RUBY_GC_STRESS: "1"
|
|
129
|
+
commands:
|
|
130
|
+
- brew install --quiet ruby@4.0
|
|
131
|
+
- export PATH="$(brew --prefix ruby@4.0)/bin:$PATH"
|
|
132
|
+
- bundle config set --local path .bundle
|
|
133
|
+
- ruby -v
|
|
134
|
+
- bundle install
|
|
135
|
+
- bundle exec rake ci
|
|
136
|
+
|
|
68
137
|
- label: ":ruby: Ruby head"
|
|
69
138
|
soft_fail: true
|
|
70
139
|
agents:
|
|
@@ -92,3 +161,34 @@ steps:
|
|
|
92
161
|
- ruby -v
|
|
93
162
|
- bundle install
|
|
94
163
|
- bundle exec rake ci
|
|
164
|
+
|
|
165
|
+
- label: ":ruby: Ruby head +GC.stress"
|
|
166
|
+
soft_fail: true
|
|
167
|
+
agents:
|
|
168
|
+
queue: macos
|
|
169
|
+
env:
|
|
170
|
+
RUBY_GC_STRESS: "1"
|
|
171
|
+
commands:
|
|
172
|
+
- brew unlink ruby
|
|
173
|
+
- brew install --HEAD --quiet ruby
|
|
174
|
+
- export PATH="$(brew --prefix ruby)/bin:$PATH"
|
|
175
|
+
- bundle config set --local path .bundle
|
|
176
|
+
- ruby -v
|
|
177
|
+
- bundle install
|
|
178
|
+
- bundle exec rake ci
|
|
179
|
+
|
|
180
|
+
- label: ":ruby: Ruby head +YJIT +GC.stress"
|
|
181
|
+
soft_fail: true
|
|
182
|
+
agents:
|
|
183
|
+
queue: macos
|
|
184
|
+
env:
|
|
185
|
+
RUBY_YJIT_ENABLE: "1"
|
|
186
|
+
RUBY_GC_STRESS: "1"
|
|
187
|
+
commands:
|
|
188
|
+
- brew unlink ruby
|
|
189
|
+
- brew install --HEAD --quiet ruby
|
|
190
|
+
- export PATH="$(brew --prefix ruby)/bin:$PATH"
|
|
191
|
+
- bundle config set --local path .bundle
|
|
192
|
+
- ruby -v
|
|
193
|
+
- bundle install
|
|
194
|
+
- bundle exec rake ci
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.13.0] - 2026-07-21
|
|
4
|
+
|
|
5
|
+
- Tune BPF reuseport routing to spread bursts across near-idle workers
|
|
6
|
+
|
|
7
|
+
## [0.12.0] - 2026-07-19
|
|
8
|
+
|
|
9
|
+
- Add `refork_after` and `before_refork` for reforking workers off a warmed source
|
|
10
|
+
- Add `before_fork`, `before_worker_boot`, and `before_worker_shutdown` hooks
|
|
11
|
+
- Sync `$stdout` and `$stderr` writes so info-level logs flush immediately
|
|
12
|
+
- Break reuseport routing ties by 4-tuple hash instead of a random draw
|
|
13
|
+
|
|
3
14
|
## [0.11.0] - 2026-07-12
|
|
4
15
|
|
|
5
16
|
- Yield subsequent HTTP/1.1 keep-alive requests to the thread pool only under saturation
|
data/README.md
CHANGED
|
@@ -36,23 +36,23 @@ run proc { |_env| [200, { "content-type" => "text/plain" }, ["Hello, World!"]] }
|
|
|
36
36
|
|
|
37
37
|
```
|
|
38
38
|
> bundle exec raptor -w 4 -t 3 hello_world.ru
|
|
39
|
-
[Raptor
|
|
40
|
-
[Raptor
|
|
41
|
-
[Raptor
|
|
42
|
-
[Raptor
|
|
43
|
-
[Raptor
|
|
44
|
-
[Raptor
|
|
45
|
-
[Raptor
|
|
46
|
-
[Raptor
|
|
47
|
-
[Raptor
|
|
48
|
-
[Raptor
|
|
49
|
-
[Raptor
|
|
50
|
-
[Raptor
|
|
51
|
-
[Raptor
|
|
52
|
-
[Raptor
|
|
53
|
-
[Raptor
|
|
54
|
-
[Raptor
|
|
55
|
-
[Raptor
|
|
39
|
+
[Raptor 59013|Main|Main] Cluster initializing:
|
|
40
|
+
[Raptor 59013|Main|Main] ├─ Version: 0.13.0
|
|
41
|
+
[Raptor 59013|Main|Main] ├─ Ruby Version: ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [arm64-darwin23]
|
|
42
|
+
[Raptor 59013|Main|Main] ├─ Environment: development
|
|
43
|
+
[Raptor 59013|Main|Main] ├─ Master PID: 59013
|
|
44
|
+
[Raptor 59013|Main|Main] │ └─ 4 worker processes
|
|
45
|
+
[Raptor 59013|Main|Main] │ ├─ 1 server thread
|
|
46
|
+
[Raptor 59013|Main|Main] │ ├─ 1 reactor thread
|
|
47
|
+
[Raptor 59013|Main|Main] │ ├─ 1 pipeline ractor
|
|
48
|
+
[Raptor 59013|Main|Main] │ ├─ 1 pipeline collector thread
|
|
49
|
+
[Raptor 59013|Main|Main] │ ├─ 3 worker threads
|
|
50
|
+
[Raptor 59013|Main|Main] │ └─ 1 stats thread
|
|
51
|
+
[Raptor 59013|Main|Main] └─ Listening on 0.0.0.0:9292
|
|
52
|
+
[Raptor 59023|Main|Main] Worker 0 booted
|
|
53
|
+
[Raptor 59024|Main|Main] Worker 1 booted
|
|
54
|
+
[Raptor 59025|Main|Main] Worker 2 booted
|
|
55
|
+
[Raptor 59026|Main|Main] Worker 3 booted
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
```
|
|
@@ -79,15 +79,16 @@ The config file is a Ruby file that evaluates to a hash of options. By default R
|
|
|
79
79
|
```ruby
|
|
80
80
|
# raptor.rb
|
|
81
81
|
|
|
82
|
+
# Every key below is set to its default value; only include the ones you want to override.
|
|
82
83
|
{
|
|
83
84
|
binds: ["tcp://0.0.0.0:9292"],
|
|
84
85
|
socket_backlog: 1024,
|
|
85
86
|
drain_accept_queue: false,
|
|
86
|
-
workers: 4,
|
|
87
|
+
workers: 4, # `Etc.nprocessors`
|
|
87
88
|
ractors: 1,
|
|
88
89
|
threads: 3,
|
|
89
90
|
chdir: nil,
|
|
90
|
-
environment: nil,
|
|
91
|
+
environment: nil, # falls back to `RAILS_ENV`, then `RACK_ENV`, then `"development"`
|
|
91
92
|
connection: {
|
|
92
93
|
first_data_timeout: 30,
|
|
93
94
|
chunk_data_timeout: 10,
|
|
@@ -106,6 +107,11 @@ The config file is a Ruby file that evaluates to a hash of options. By default R
|
|
|
106
107
|
worker_timeout: 60,
|
|
107
108
|
worker_drain_timeout: 25,
|
|
108
109
|
worker_shutdown_timeout: 30,
|
|
110
|
+
refork_after: 1000, # `nil` on non-Linux
|
|
111
|
+
before_fork: [],
|
|
112
|
+
before_worker_boot: [],
|
|
113
|
+
before_worker_shutdown: [],
|
|
114
|
+
before_refork: [],
|
|
109
115
|
stats_file: "tmp/raptor.json",
|
|
110
116
|
pid_file: nil,
|
|
111
117
|
stdout_file: nil,
|
|
@@ -187,20 +193,30 @@ Worker 1 (phase 0): pid=91351, requests=1199, busy=1/3, backlog=0, booted, last_
|
|
|
187
193
|
|
|
188
194
|
## (Micro) Benchmarks
|
|
189
195
|
|
|
190
|
-
Raptor 0.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
Raptor 0.13.0 vs Puma 8.0.2 vs Falcon 0.55.5 across two workload profiles. **IO-bound** is a GET endpoint that
|
|
197
|
+
interleaves 5-10 short sleeps (total 2.5-15ms) with small CPU work, simulating a read path that makes several DB or
|
|
198
|
+
cache calls. **CPU-bound** is a POST endpoint that accepts a small JSON body, interleaves 3-5 chunks of JSON item
|
|
199
|
+
building (total 450-1500 items) with sub-100µs sleeps, and returns the built array, simulating a write path that does
|
|
200
|
+
most of its work in Ruby with a few near-zero-cost cache hits.
|
|
201
|
+
|
|
202
|
+
Each cell reports the median throughput and median p95 latency independently across 5 runs, so the two numbers in a row
|
|
203
|
+
may come from different runs. Every run starts a fresh server process so the samples are independent of each other;
|
|
204
|
+
state accumulated in a previous run cannot bias the next. Across the whole table, the widest spread
|
|
205
|
+
((max - min) / 2 / median) between runs of a single cell was ±30.0% for throughput
|
|
206
|
+
and ±22.8% for p95.
|
|
207
|
+
|
|
208
|
+
| Protocol | Workload | Raptor req/s | Raptor p95 | Puma req/s | Puma p95 | vs Puma req/s | vs Puma p95 | Falcon req/s | Falcon p95 | vs Falcon req/s | vs Falcon p95 |
|
|
209
|
+
| --------------------- | -------- | ------------ | ---------- | ----------- | -------- | ------------- | ----------- | ------------ | ---------- | --------------- | ------------- |
|
|
210
|
+
| HTTP/1.1 | IO | 1.39k req/s | 50.20 ms | 0.96k req/s | 66.20 ms | 44.1% higher | 24.2% lower | 4.54k req/s | 15.00 ms | 69.4% lower | 234.7% higher |
|
|
211
|
+
| HTTP/1.1 | CPU | 4.55k req/s | 18.10 ms | 3.64k req/s | 16.50 ms | 24.9% higher | 9.7% higher | 3.87k req/s | 15.00 ms | 17.5% higher | 20.7% higher |
|
|
212
|
+
| HTTP/1.1 (keep-alive) | IO | 1.42k req/s | 30.00 ms | 0.92k req/s | 65.80 ms | 54.8% higher | 54.4% lower | 4.08k req/s | 16.70 ms | 65.3% lower | 79.6% higher |
|
|
213
|
+
| HTTP/1.1 (keep-alive) | CPU | 4.51k req/s | 11.20 ms | 3.77k req/s | 17.50 ms | 19.8% higher | 36.0% lower | 4.00k req/s | 16.50 ms | 12.9% higher | 32.1% lower |
|
|
214
|
+
| HTTP/2 | IO | 0.71k req/s | 85.84 ms | N/A | N/A | - | - | 3.88k req/s | 17.43 ms | 81.7% lower | 392.3% higher |
|
|
215
|
+
| HTTP/2 | CPU | 4.07k req/s | 21.85 ms | N/A | N/A | - | - | 4.33k req/s | 30.84 ms | 6.0% lower | 29.2% lower |
|
|
201
216
|
|
|
202
217
|
> ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [aarch64-linux]
|
|
203
|
-
> 4
|
|
218
|
+
> 4 worker processes; Raptor and Puma run 3 threads per worker, Falcon runs unbounded fibers per worker;
|
|
219
|
+
> 48 concurrent HTTP/1.1 client connections; 16 concurrent HTTP/2 client connections × 3 streams each
|
|
204
220
|
|
|
205
221
|
See [bin/benchmark](bin/benchmark) for more details.
|
|
206
222
|
|