raptor 0.22.3 → 0.23.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/Dockerfile +3 -1
  4. data/README.md +38 -31
  5. data/docs/raptor-vs-puma.md +44 -38
  6. data/docs/talk.md +1295 -0
  7. data/ext/raptor_bpf/reuseport_select.bpf.c +18 -9
  8. data/ext/raptor_http/extconf.rb +2 -0
  9. data/ext/raptor_http/raptor_http.c +91 -119
  10. data/ext/raptor_http2/raptor_http2.c +272 -223
  11. data/ext/raptor_native/raptor_native.c +38 -20
  12. data/lib/rackup/handler/raptor.rb +12 -11
  13. data/lib/raptor/binder.rb +12 -12
  14. data/lib/raptor/cli.rb +18 -18
  15. data/lib/raptor/cluster.rb +44 -44
  16. data/lib/raptor/control_server.rb +3 -2
  17. data/lib/raptor/detached_body.rb +6 -2
  18. data/lib/raptor/http.rb +7 -5
  19. data/lib/raptor/http1.rb +232 -207
  20. data/lib/raptor/http2.rb +312 -265
  21. data/lib/raptor/reactor.rb +138 -148
  22. data/lib/raptor/reuseport_bpf.rb +62 -38
  23. data/lib/raptor/server.rb +45 -34
  24. data/lib/raptor/stats.rb +15 -3
  25. data/lib/raptor/thread_locals.rb +4 -3
  26. data/lib/raptor/version.rb +1 -1
  27. data/sig/generated/rackup/handler/raptor.rbs +2 -1
  28. data/sig/generated/raptor/binder.rbs +9 -9
  29. data/sig/generated/raptor/cli.rbs +6 -6
  30. data/sig/generated/raptor/cluster.rbs +9 -9
  31. data/sig/generated/raptor/control_server.rbs +2 -1
  32. data/sig/generated/raptor/detached_body.rbs +5 -1
  33. data/sig/generated/raptor/http.rbs +3 -3
  34. data/sig/generated/raptor/http1.rbs +100 -91
  35. data/sig/generated/raptor/http2.rbs +200 -189
  36. data/sig/generated/raptor/reactor.rbs +107 -118
  37. data/sig/generated/raptor/reuseport_bpf.rbs +54 -17
  38. data/sig/generated/raptor/server.rbs +26 -26
  39. data/sig/generated/raptor/stats.rbs +3 -2
  40. data/sig/generated/raptor/thread_locals.rbs +4 -3
  41. metadata +2 -2
  42. data/docs/brisrails-talk.md +0 -2398
@@ -19,9 +19,10 @@ module Raptor
19
19
  # @rbs @client: Atom
20
20
  # @rbs @thread: Thread?
21
21
 
22
- # Creates a control server for `url` without binding it.
22
+ # Creates a new ControlServer for `url` without binding it.
23
23
  #
24
24
  # @param url [String] `unix://` URL to listen on
25
+ # @yield for each stats request
25
26
  # @yieldreturn [Hash] cluster statistics
26
27
  # @return [void]
27
28
  # @raise [ArgumentError] if the URL is not a Unix socket
@@ -131,7 +132,7 @@ module Raptor
131
132
  # @rbs (UNIXSocket client) -> void
132
133
  def handle(client)
133
134
  request_line = client.gets
134
- while line = client.gets
135
+ while (line = client.gets)
135
136
  break if line == "\r\n"
136
137
  end
137
138
 
@@ -66,6 +66,7 @@ module Raptor
66
66
  #
67
67
  # @param max_buffer_size [Integer] maximum body bytes waiting to be written
68
68
  # @return [void]
69
+ # @raise [ArgumentError] if `max_buffer_size` is not positive
69
70
  #
70
71
  # @rbs (?max_buffer_size: Integer) -> void
71
72
  def initialize(max_buffer_size: DEFAULT_MAX_BUFFER_SIZE)
@@ -84,6 +85,7 @@ module Raptor
84
85
  # Registers a callback that runs on the request thread once the server
85
86
  # accepts the response stream.
86
87
  #
88
+ # @yield once the response stream opens
87
89
  # @yieldparam stream [DetachedBody] the opened response stream
88
90
  # @return [DetachedBody]
89
91
  #
@@ -95,6 +97,7 @@ module Raptor
95
97
 
96
98
  # Registers a callback for when the response stream closes.
97
99
  #
100
+ # @yield once the response stream closes
98
101
  # @yieldparam reason [Symbol] why the stream closed
99
102
  # @return [DetachedBody]
100
103
  #
@@ -108,6 +111,7 @@ module Raptor
108
111
  #
109
112
  # @param chunk [String] response body bytes
110
113
  # @return [Symbol] `:accepted`, `:full`, or `:closed`
114
+ # @raise [TypeError] if the chunk is not a String
111
115
  #
112
116
  # @rbs (String chunk) -> Symbol
113
117
  def try_write(chunk)
@@ -150,7 +154,7 @@ module Raptor
150
154
  result
151
155
  end
152
156
 
153
- # Finishes the body after all accepted bytes have been written.
157
+ # Marks the body complete; the stream finishes once buffered bytes are written.
154
158
  #
155
159
  # @param trailers [Hash] trailing response headers
156
160
  # @return [void]
@@ -158,7 +162,7 @@ module Raptor
158
162
  # @rbs (?trailers: Hash[String, String | Array[String]]) -> void
159
163
  def close(trailers: {})
160
164
  trailers = trailers.to_h do |name, value|
161
- value = value.is_a?(Array) ? value.map { _1.dup.freeze }.freeze : value.dup.freeze
165
+ value = value.is_a?(Array) ? value.map { |item| item.dup.freeze }.freeze : value.dup.freeze
162
166
  [name.dup.freeze, value]
163
167
  end.freeze
164
168
  wake = false
data/lib/raptor/http.rb CHANGED
@@ -20,7 +20,7 @@ module Raptor
20
20
  REMOTE_ADDR = "REMOTE_ADDR"
21
21
  REQUEST_URI = "REQUEST_URI"
22
22
  SERVER_SOFTWARE = "SERVER_SOFTWARE"
23
- SERVER_SOFTWARE_VALUE = "Raptor/#{Raptor::VERSION}".freeze
23
+ SERVER_SOFTWARE_VALUE = "Raptor/#{VERSION}".freeze
24
24
 
25
25
  class WriteError < StandardError
26
26
  # @rbs () -> String
@@ -56,6 +56,7 @@ module Raptor
56
56
  bytes += socket.write_nonblock(bytes.zero? ? string : string.byteslice(bytes..-1))
57
57
  rescue IO::WaitWritable
58
58
  raise WriteError unless socket.wait_writable(timeout)
59
+
59
60
  retry
60
61
  rescue IOError
61
62
  raise WriteError
@@ -79,9 +80,10 @@ module Raptor
79
80
  return if total.zero?
80
81
 
81
82
  begin
82
- written = Raptor::VectorIO.writev_nonblock(socket, strings)
83
+ written = VectorIO.writev_nonblock(socket, strings)
83
84
  rescue IO::WaitWritable
84
85
  raise WriteError unless socket.wait_writable(timeout)
86
+
85
87
  retry
86
88
  rescue IOError
87
89
  raise WriteError
@@ -113,7 +115,7 @@ module Raptor
113
115
  # @rbs (Hash[String, untyped] env_template, Integer? max_body_size) -> ^(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
114
116
  def self.parser_worker(env_template, max_body_size)
115
117
  proc do |data|
116
- Raptor::Http1.parse(data, env_template, max_body_size)
118
+ Http1.parse(data, env_template, max_body_size)
117
119
  end
118
120
  end
119
121
 
@@ -121,12 +123,12 @@ module Raptor
121
123
  # registration order, rescuing any that raise.
122
124
  #
123
125
  # @param env [Hash, nil] the Rack environment
124
- # @param status [Integer, nil] the response status code
126
+ # @param status [Object, nil] the status returned by the app, if any
125
127
  # @param headers [Hash, nil] the response headers
126
128
  # @param error [Exception, nil] any error raised during processing, or nil on success
127
129
  # @return [void]
128
130
  #
129
- # @rbs (Hash[String, untyped]? env, Integer? status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
131
+ # @rbs (Hash[String, untyped]? env, untyped status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
130
132
  def self.call_response_finished(env, status, headers, error)
131
133
  return unless env && env[Rack::RACK_RESPONSE_FINISHED].is_a?(Array)
132
134