raptor 0.22.0 → 0.22.2
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 +10 -0
- data/README.md +15 -15
- data/docs/raptor-vs-puma.md +1 -1
- data/lib/raptor/cli.rb +5 -4
- data/lib/raptor/cluster.rb +4 -4
- data/lib/raptor/control_server.rb +36 -17
- data/lib/raptor/detached_body.rb +47 -4
- data/lib/raptor/http.rb +10 -0
- data/lib/raptor/http1.rb +27 -3
- data/lib/raptor/http2.rb +33 -9
- data/lib/raptor/reactor.rb +128 -19
- data/lib/raptor/thread_locals.rb +4 -2
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/raptor/control_server.rbs +17 -5
- data/sig/generated/raptor/detached_body.rbs +45 -1
- data/sig/generated/raptor/http.rbs +8 -0
- data/sig/generated/raptor/http1.rbs +24 -0
- data/sig/generated/raptor/http2.rbs +29 -6
- data/sig/generated/raptor/reactor.rbs +105 -3
- data/sig/generated/raptor/thread_locals.rbs +3 -1
- metadata +1 -1
|
@@ -43,6 +43,11 @@ module Raptor
|
|
|
43
43
|
|
|
44
44
|
# Attaches a response body that outlives its application thread.
|
|
45
45
|
#
|
|
46
|
+
# @param stream_id [Integer] the HTTP/2 stream identifier
|
|
47
|
+
# @param body [DetachedBody] the response body
|
|
48
|
+
# @param finished [Proc] called with the close reason
|
|
49
|
+
# @return [Boolean] whether the reactor accepted the body
|
|
50
|
+
#
|
|
46
51
|
# @rbs (Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> bool
|
|
47
52
|
def attach_body: (Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> bool
|
|
48
53
|
end
|
|
@@ -257,8 +262,6 @@ module Raptor
|
|
|
257
262
|
def closed?: () -> bool
|
|
258
263
|
end
|
|
259
264
|
|
|
260
|
-
EAGER_READ_TIMEOUT: ::Float
|
|
261
|
-
|
|
262
265
|
EAGER_READ_BUFFER_SIZE: untyped
|
|
263
266
|
|
|
264
267
|
EAGER_MAX_ROUNDS: ::Integer
|
|
@@ -468,8 +471,8 @@ module Raptor
|
|
|
468
471
|
# @rbs (FlowControl flow_control, Hash[Symbol, untyped] result) -> void
|
|
469
472
|
def apply_flow_control_updates: (FlowControl flow_control, Hash[Symbol, untyped] result) -> void
|
|
470
473
|
|
|
471
|
-
# Reads the next frame batch from `socket`
|
|
472
|
-
#
|
|
474
|
+
# Reads the next frame batch from `socket` if it has already arrived,
|
|
475
|
+
# without waiting on the shared collector thread.
|
|
473
476
|
#
|
|
474
477
|
# @param socket [OpenSSL::SSL::SSLSocket] the connection socket
|
|
475
478
|
# @return [String, nil] the bytes read, or nil if nothing was available
|
|
@@ -494,13 +497,33 @@ module Raptor
|
|
|
494
497
|
|
|
495
498
|
# Calls the Rack app and writes its response for one stream.
|
|
496
499
|
#
|
|
500
|
+
# @param socket [OpenSSL::SSL::SSLSocket] the connection socket
|
|
501
|
+
# @param writer [Writer] lock-free frame writer for the connection
|
|
502
|
+
# @param flow_control [FlowControl] per-connection outbound flow controller
|
|
503
|
+
# @param stream_id [Integer] the HTTP/2 stream identifier
|
|
504
|
+
# @param headers [Array<Array(String, String)>] request headers
|
|
505
|
+
# @param body [String] request body
|
|
506
|
+
# @param remote_addr [String] the client IP address
|
|
507
|
+
# @return [void]
|
|
508
|
+
#
|
|
497
509
|
# @rbs (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Array[[String, String]] headers, String body, remote_addr: String) -> void
|
|
498
510
|
def perform_stream_request: (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Array[[ String, String ]] headers, String body, remote_addr: String) -> void
|
|
499
511
|
|
|
500
512
|
# Starts a detached HTTP/2 response after writing its response headers.
|
|
501
513
|
#
|
|
502
|
-
# @
|
|
503
|
-
|
|
514
|
+
# @param socket [OpenSSL::SSL::SSLSocket] the connection socket
|
|
515
|
+
# @param writer [Writer] lock-free frame writer for the connection
|
|
516
|
+
# @param flow_control [FlowControl] per-connection outbound flow controller
|
|
517
|
+
# @param stream_id [Integer] the HTTP/2 stream identifier
|
|
518
|
+
# @param status [Integer] HTTP status code
|
|
519
|
+
# @param headers [Hash] response headers from the Rack application
|
|
520
|
+
# @param body [DetachedBody] the response body
|
|
521
|
+
# @param finished [Proc] called with the close reason
|
|
522
|
+
# @yield once the response headers are queued
|
|
523
|
+
# @return [void]
|
|
524
|
+
#
|
|
525
|
+
# @rbs (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, DetachedBody body, ^(Symbol) -> void finished) { () -> void } -> void
|
|
526
|
+
def write_http2_detached_response: (OpenSSL::SSL::SSLSocket socket, Writer writer, FlowControl flow_control, Integer stream_id, Integer status, Hash[String, String | Array[String]] headers, DetachedBody body, ^(Symbol) -> void finished) { () -> void } -> void
|
|
504
527
|
|
|
505
528
|
# Writes a Rack response as HTTP/2 frames to the socket, partitioning
|
|
506
529
|
# DATA frames through `flow_control` to fit within the peer's windows.
|
|
@@ -60,9 +60,17 @@ module Raptor
|
|
|
60
60
|
# @rbs attr_reader output: Array[String]
|
|
61
61
|
attr_reader output: untyped
|
|
62
62
|
|
|
63
|
+
# Creates empty connection I/O state for reactor-owned writes.
|
|
64
|
+
#
|
|
65
|
+
# @return [void]
|
|
66
|
+
#
|
|
63
67
|
# @rbs () -> void
|
|
64
68
|
def initialize: () -> void
|
|
65
69
|
|
|
70
|
+
# Returns whether the connection has no output waiting to be written.
|
|
71
|
+
#
|
|
72
|
+
# @return [Boolean]
|
|
73
|
+
#
|
|
66
74
|
# @rbs () -> bool
|
|
67
75
|
def empty?: () -> bool
|
|
68
76
|
end
|
|
@@ -84,9 +92,19 @@ module Raptor
|
|
|
84
92
|
# @rbs attr_reader state: Hash[Symbol, untyped]
|
|
85
93
|
attr_reader state: untyped
|
|
86
94
|
|
|
95
|
+
# Creates I/O state for an HTTP/1.x detached response.
|
|
96
|
+
#
|
|
97
|
+
# @param body [DetachedBody] the response body
|
|
98
|
+
# @param state [Hash] connection state restored after the response finishes
|
|
99
|
+
# @return [void]
|
|
100
|
+
#
|
|
87
101
|
# @rbs (DetachedBody body, Hash[Symbol, untyped] state) -> void
|
|
88
102
|
def initialize: (DetachedBody body, Hash[Symbol, untyped] state) -> void
|
|
89
103
|
|
|
104
|
+
# Returns whether the connection has no output or detached body remaining.
|
|
105
|
+
#
|
|
106
|
+
# @return [Boolean]
|
|
107
|
+
#
|
|
90
108
|
# @rbs () -> bool
|
|
91
109
|
def empty?: () -> bool
|
|
92
110
|
end
|
|
@@ -105,9 +123,17 @@ module Raptor
|
|
|
105
123
|
# @rbs attr_reader budget: DetachedBody::Budget
|
|
106
124
|
attr_reader budget: untyped
|
|
107
125
|
|
|
126
|
+
# Creates empty I/O state for an HTTP/2 connection and its detached streams.
|
|
127
|
+
#
|
|
128
|
+
# @return [void]
|
|
129
|
+
#
|
|
108
130
|
# @rbs () -> void
|
|
109
131
|
def initialize: () -> void
|
|
110
132
|
|
|
133
|
+
# Returns whether the connection has no output or detached streams remaining.
|
|
134
|
+
#
|
|
135
|
+
# @return [Boolean]
|
|
136
|
+
#
|
|
111
137
|
# @rbs () -> bool
|
|
112
138
|
def empty?: () -> bool
|
|
113
139
|
end
|
|
@@ -116,9 +142,7 @@ module Raptor
|
|
|
116
142
|
|
|
117
143
|
DETACHED_CONNECTION_BUFFER_SIZE: untyped
|
|
118
144
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
DETACHED_MAX_FRAMES: ::Integer
|
|
145
|
+
DETACHED_WRITE_BATCH: ::Integer
|
|
122
146
|
|
|
123
147
|
DETACHED_WORKER_BUFFER_SIZE: untyped
|
|
124
148
|
|
|
@@ -126,6 +150,8 @@ module Raptor
|
|
|
126
150
|
|
|
127
151
|
@timeouts: RedBlackTree[TimeoutClient]
|
|
128
152
|
|
|
153
|
+
@io_applied: AtomicConditionVariable
|
|
154
|
+
|
|
129
155
|
@io_queue: AtomicQueue
|
|
130
156
|
|
|
131
157
|
@queue: Queue[TCPSocket]
|
|
@@ -184,6 +210,7 @@ module Raptor
|
|
|
184
210
|
# @param connection_options [Hash] per-connection timeout configuration
|
|
185
211
|
# @option connection_options [Integer] :first_data_timeout timeout for initial data
|
|
186
212
|
# @option connection_options [Integer] :chunk_data_timeout timeout for subsequent chunks
|
|
213
|
+
# @option connection_options [Integer] :write_timeout timeout for non-blocking writes
|
|
187
214
|
# @param http1_options [Hash] HTTP/1.1-specific configuration
|
|
188
215
|
# @option http1_options [Integer] :persistent_data_timeout timeout for keep-alive idle connections
|
|
189
216
|
# @param http2_options [Hash] HTTP/2-specific configuration
|
|
@@ -273,6 +300,13 @@ module Raptor
|
|
|
273
300
|
|
|
274
301
|
# Attaches a detached response body to an HTTP/1.x connection.
|
|
275
302
|
#
|
|
303
|
+
# @param socket [TCPSocket] the client socket
|
|
304
|
+
# @param id [Integer] unique client identifier
|
|
305
|
+
# @param body [DetachedBody] the response body
|
|
306
|
+
# @param state [Hash] connection state restored once the response finishes
|
|
307
|
+
# @param finished [Proc] called with the close reason
|
|
308
|
+
# @return [Boolean] whether the body was attached
|
|
309
|
+
#
|
|
276
310
|
# @rbs (TCPSocket socket, Integer id, DetachedBody body, Hash[Symbol, untyped] state, ^(Symbol) -> void finished) -> bool
|
|
277
311
|
def attach_http1_body: (TCPSocket socket, Integer id, DetachedBody body, Hash[Symbol, untyped] state, ^(Symbol) -> void finished) -> bool
|
|
278
312
|
|
|
@@ -308,22 +342,38 @@ module Raptor
|
|
|
308
342
|
|
|
309
343
|
# Attaches a detached response body to an HTTP/2 stream.
|
|
310
344
|
#
|
|
345
|
+
# @param id [Integer] unique connection identifier
|
|
346
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
347
|
+
# @param body [DetachedBody] the response body
|
|
348
|
+
# @param finished [Proc] called with the close reason
|
|
349
|
+
# @return [Boolean] whether the body was attached
|
|
350
|
+
#
|
|
311
351
|
# @rbs (Integer id, Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> bool
|
|
312
352
|
def attach_http2_body: (Integer id, Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> bool
|
|
313
353
|
|
|
314
354
|
# Reconsiders detached streams after an outbound window update.
|
|
315
355
|
#
|
|
356
|
+
# @param id [Integer] unique connection identifier
|
|
357
|
+
# @return [void]
|
|
358
|
+
#
|
|
316
359
|
# @rbs (Integer id) -> void
|
|
317
360
|
def resume_http2_bodies: (Integer id) -> void
|
|
318
361
|
|
|
319
362
|
# Cancels a detached response stream.
|
|
320
363
|
#
|
|
364
|
+
# @param id [Integer] unique connection identifier
|
|
365
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
366
|
+
# @return [void]
|
|
367
|
+
#
|
|
321
368
|
# @rbs (Integer id, Integer stream_id) -> void
|
|
322
369
|
def cancel_http2_body: (Integer id, Integer stream_id) -> void
|
|
323
370
|
|
|
324
371
|
# Waits for detached responses to finish, then cancels any that outlive
|
|
325
372
|
# the worker drain period.
|
|
326
373
|
#
|
|
374
|
+
# @param timeout [Numeric] seconds to wait before cancelling open bodies
|
|
375
|
+
# @return [void]
|
|
376
|
+
#
|
|
327
377
|
# @rbs (Numeric timeout) -> void
|
|
328
378
|
def drain_detached_bodies: (Numeric timeout) -> void
|
|
329
379
|
|
|
@@ -418,61 +468,109 @@ module Raptor
|
|
|
418
468
|
|
|
419
469
|
# Adds a detached body to an HTTP/1.x connection.
|
|
420
470
|
#
|
|
471
|
+
# @param socket [TCPSocket] the client socket
|
|
472
|
+
# @param id [Integer] unique client identifier
|
|
473
|
+
# @param body [DetachedBody] the response body
|
|
474
|
+
# @param state [Hash] connection state restored once the response finishes
|
|
475
|
+
# @param finished [Proc] called with the close reason
|
|
476
|
+
# @return [void]
|
|
477
|
+
#
|
|
421
478
|
# @rbs (TCPSocket socket, Integer id, DetachedBody body, Hash[Symbol, untyped] state, ^(Symbol) -> void finished) -> void
|
|
422
479
|
def attach_http1_detached_body: (TCPSocket socket, Integer id, DetachedBody body, Hash[Symbol, untyped] state, ^(Symbol) -> void finished) -> void
|
|
423
480
|
|
|
424
481
|
# Writes buffered HTTP/1.x body chunks without blocking.
|
|
425
482
|
#
|
|
483
|
+
# @param id [Integer] unique client identifier
|
|
484
|
+
# @return [void]
|
|
485
|
+
#
|
|
426
486
|
# @rbs (Integer id) -> void
|
|
427
487
|
def flush_http1_detached_body: (Integer id) -> void
|
|
428
488
|
|
|
429
489
|
# Finishes an HTTP/1.x detached response and either reuses or closes its connection.
|
|
430
490
|
#
|
|
491
|
+
# @param id [Integer] unique client identifier
|
|
492
|
+
# @param io [Http1IO] connection I/O state
|
|
493
|
+
# @return [void]
|
|
494
|
+
#
|
|
431
495
|
# @rbs (Integer id, Http1IO io) -> void
|
|
432
496
|
def finish_http1_detached_body: (Integer id, Http1IO io) -> void
|
|
433
497
|
|
|
434
498
|
# Cancels an HTTP/1.x detached response and closes its connection.
|
|
435
499
|
#
|
|
500
|
+
# @param id [Integer] unique client identifier
|
|
501
|
+
# @param reason [Symbol] why the response closed
|
|
502
|
+
# @return [void]
|
|
503
|
+
#
|
|
436
504
|
# @rbs (Integer id, Symbol reason) -> void
|
|
437
505
|
def remove_http1_detached_body: (Integer id, Symbol reason) -> void
|
|
438
506
|
|
|
439
507
|
# Adds a detached body to an HTTP/2 stream.
|
|
440
508
|
#
|
|
509
|
+
# @param id [Integer] unique connection identifier
|
|
510
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
511
|
+
# @param body [DetachedBody] the response body
|
|
512
|
+
# @param finished [Proc] called with the close reason
|
|
513
|
+
# @return [void]
|
|
514
|
+
#
|
|
441
515
|
# @rbs (Integer id, Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> void
|
|
442
516
|
def attach_http2_detached_body: (Integer id, Integer stream_id, DetachedBody body, ^(Symbol) -> void finished) -> void
|
|
443
517
|
|
|
444
518
|
# Marks an HTTP/2 detached stream eligible for fair scheduling.
|
|
445
519
|
#
|
|
520
|
+
# @param id [Integer] unique connection identifier
|
|
521
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
522
|
+
# @return [void]
|
|
523
|
+
#
|
|
446
524
|
# @rbs (Integer id, Integer stream_id) -> void
|
|
447
525
|
def mark_http2_detached_body_ready: (Integer id, Integer stream_id) -> void
|
|
448
526
|
|
|
449
527
|
# Marks every HTTP/2 detached stream eligible after flow-control capacity changes.
|
|
450
528
|
#
|
|
529
|
+
# @param id [Integer] unique connection identifier
|
|
530
|
+
# @return [void]
|
|
531
|
+
#
|
|
451
532
|
# @rbs (Integer id) -> void
|
|
452
533
|
def resume_http2_detached_bodies: (Integer id) -> void
|
|
453
534
|
|
|
454
535
|
# Writes HTTP/2 detached streams in round-robin order without waiting for flow control.
|
|
455
536
|
#
|
|
537
|
+
# @param id [Integer] unique connection identifier
|
|
538
|
+
# @return [void]
|
|
539
|
+
#
|
|
456
540
|
# @rbs (Integer id) -> void
|
|
457
541
|
def flush_http2_detached_bodies: (Integer id) -> void
|
|
458
542
|
|
|
459
543
|
# Finishes an HTTP/2 detached stream with DATA or trailing HEADERS.
|
|
460
544
|
#
|
|
545
|
+
# @param id [Integer] unique connection identifier
|
|
546
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
547
|
+
# @param body [DetachedBody] the response body
|
|
548
|
+
# @return [void]
|
|
549
|
+
#
|
|
461
550
|
# @rbs (Integer id, Integer stream_id, DetachedBody body) -> void
|
|
462
551
|
def finish_http2_detached_body: (Integer id, Integer stream_id, DetachedBody body) -> void
|
|
463
552
|
|
|
464
553
|
# Removes an HTTP/2 detached stream and schedules its close callback.
|
|
465
554
|
#
|
|
555
|
+
# @param id [Integer] unique connection identifier
|
|
556
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
557
|
+
# @param reason [Symbol] why the stream closed
|
|
558
|
+
# @return [void]
|
|
559
|
+
#
|
|
466
560
|
# @rbs (Integer id, Integer stream_id, Symbol reason) -> void
|
|
467
561
|
def remove_http2_detached_body: (Integer id, Integer stream_id, Symbol reason) -> void
|
|
468
562
|
|
|
469
563
|
# Cancels every detached response during worker shutdown.
|
|
470
564
|
#
|
|
565
|
+
# @return [void]
|
|
566
|
+
#
|
|
471
567
|
# @rbs () -> void
|
|
472
568
|
def cancel_detached_bodies: () -> void
|
|
473
569
|
|
|
474
570
|
# Records one detached stream finishing.
|
|
475
571
|
#
|
|
572
|
+
# @return [void]
|
|
573
|
+
#
|
|
476
574
|
# @rbs () -> void
|
|
477
575
|
def detached_body_removed: () -> void
|
|
478
576
|
|
|
@@ -593,6 +691,10 @@ module Raptor
|
|
|
593
691
|
|
|
594
692
|
# Handles readiness for an HTTP/1.x detached response.
|
|
595
693
|
#
|
|
694
|
+
# @param monitor [NIO::Monitor] ready selector monitor
|
|
695
|
+
# @param id [Integer] unique client identifier
|
|
696
|
+
# @return [void]
|
|
697
|
+
#
|
|
596
698
|
# @rbs (NIO::Monitor monitor, Integer id) -> void
|
|
597
699
|
def handle_http1_detached_monitor: (NIO::Monitor monitor, Integer id) -> void
|
|
598
700
|
|
|
@@ -8,7 +8,9 @@ module Raptor
|
|
|
8
8
|
|
|
9
9
|
# Returns a reusable value stored on the current thread.
|
|
10
10
|
#
|
|
11
|
-
# @
|
|
11
|
+
# @param key [Symbol] thread-variable key used to cache the value
|
|
12
|
+
# @yieldreturn [Object] value to store when the key is unset
|
|
13
|
+
# @return [Object] the existing or newly stored value
|
|
12
14
|
#
|
|
13
15
|
# @rbs (Symbol key) { () -> untyped } -> untyped
|
|
14
16
|
def self.fetch: (Symbol key) { () -> untyped } -> untyped
|