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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/Dockerfile +10 -2
  4. data/README.md +183 -61
  5. data/docs/assets/profile_picture.png +0 -0
  6. data/docs/assets/startup_output.svg +37 -0
  7. data/docs/raptor-vs-puma.md +104 -424
  8. data/docs/talk.md +1388 -0
  9. data/ext/raptor_bpf/reuseport_select.bpf.c +18 -9
  10. data/ext/raptor_http/extconf.rb +2 -0
  11. data/ext/raptor_http/raptor_http.c +165 -234
  12. data/ext/raptor_http2/raptor_http2.c +272 -223
  13. data/ext/raptor_native/raptor_native.c +38 -20
  14. data/lib/rackup/handler/raptor.rb +14 -12
  15. data/lib/raptor/binder.rb +12 -12
  16. data/lib/raptor/cli.rb +19 -18
  17. data/lib/raptor/cluster.rb +120 -74
  18. data/lib/raptor/control_server.rb +5 -2
  19. data/lib/raptor/detached_body.rb +6 -2
  20. data/lib/raptor/http.rb +7 -6
  21. data/lib/raptor/http1.rb +281 -234
  22. data/lib/raptor/http2.rb +356 -276
  23. data/lib/raptor/plugin.rb +98 -0
  24. data/lib/raptor/reactor.rb +138 -148
  25. data/lib/raptor/reuseport_bpf.rb +62 -38
  26. data/lib/raptor/server.rb +45 -34
  27. data/lib/raptor/stats.rb +15 -3
  28. data/lib/raptor/thread_locals.rb +4 -3
  29. data/lib/raptor/version.rb +1 -1
  30. data/sig/generated/rackup/handler/raptor.rbs +2 -1
  31. data/sig/generated/raptor/binder.rbs +9 -9
  32. data/sig/generated/raptor/cli.rbs +6 -6
  33. data/sig/generated/raptor/cluster.rbs +18 -5
  34. data/sig/generated/raptor/control_server.rbs +2 -1
  35. data/sig/generated/raptor/detached_body.rbs +5 -1
  36. data/sig/generated/raptor/http.rbs +3 -5
  37. data/sig/generated/raptor/http1.rbs +119 -102
  38. data/sig/generated/raptor/http2.rbs +204 -190
  39. data/sig/generated/raptor/plugin.rbs +52 -0
  40. data/sig/generated/raptor/reactor.rbs +107 -118
  41. data/sig/generated/raptor/reuseport_bpf.rbs +54 -17
  42. data/sig/generated/raptor/server.rbs +26 -26
  43. data/sig/generated/raptor/stats.rbs +3 -2
  44. data/sig/generated/raptor/thread_locals.rbs +4 -3
  45. metadata +6 -2
  46. data/docs/brisrails-talk.md +0 -2398
@@ -2,13 +2,16 @@
2
2
  #include <bpf/bpf_helpers.h>
3
3
 
4
4
  #define MAX_WORKERS 64
5
+ #define MAX_LISTENERS 16
6
+ #define UNAVAILABLE_LOAD 0xffffffff
5
7
 
6
- // Per-worker listening sockets, keyed by worker index.
8
+ // Per-worker listening sockets, keyed by listener index * MAX_WORKERS +
9
+ // worker index so each bound address has its own row of worker slots.
7
10
  struct {
8
11
  __uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
9
12
  __type(key, __u32);
10
13
  __type(value, __u64);
11
- __uint(max_entries, MAX_WORKERS);
14
+ __uint(max_entries, MAX_WORKERS * MAX_LISTENERS);
12
15
  } socks SEC(".maps");
13
16
 
14
17
  // Worker count at slot 0, per-worker backlog at slots 1..N.
@@ -19,10 +22,8 @@ struct {
19
22
  __uint(max_entries, MAX_WORKERS + 1);
20
23
  } loads SEC(".maps");
21
24
 
22
- // Uses the power-of-two-choices strategy and reserves the selected worker's
23
- // slot before returning. Sampling two hash-selected workers avoids
24
- // concentrating variable-cost requests, while the reservation prevents a
25
- // burst from repeatedly selecting the same reported load.
25
+ // Account for routed connections before the worker reports its new backlog,
26
+ // so bursts do not keep selecting against stale load.
26
27
  SEC("sk_reuseport")
27
28
  int select_less_loaded(struct sk_reuseport_md *ctx) {
28
29
  __u32 count_key = 0;
@@ -48,11 +49,19 @@ int select_less_loaded(struct sk_reuseport_md *ctx) {
48
49
  }
49
50
  }
50
51
 
51
- if (chosen_load) {
52
- __sync_fetch_and_add(chosen_load, 1);
52
+ // Every bound address shares this program, and the kernel only accepts a
53
+ // socket from the reuseport group the connection arrived on, so try the
54
+ // chosen worker's socket for each address until one belongs to the group.
55
+ for (__u32 listener = 0; listener < MAX_LISTENERS; listener++) {
56
+ __u32 sock_key = listener * MAX_WORKERS + chosen_idx;
57
+ if (bpf_sk_select_reuseport(ctx, &socks, &sock_key, 0) == 0) {
58
+ if (chosen_load && *chosen_load != UNAVAILABLE_LOAD) {
59
+ __sync_fetch_and_add(chosen_load, 1);
60
+ }
61
+ break;
62
+ }
53
63
  }
54
64
 
55
- bpf_sk_select_reuseport(ctx, &socks, &chosen_idx, 0);
56
65
  return SK_PASS;
57
66
  }
58
67
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "mkmf"
4
4
 
5
+ # The Ragel-generated parser compares `char` values against 0, which GCC flags
6
+ # as always true where `char` is unsigned (e.g. aarch64 Linux).
5
7
  append_cflags(["-fvisibility=hidden", "-Wno-type-limits"])
6
8
 
7
9
  create_makefile("raptor/raptor_http")