raptor 0.24.0 → 0.26.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 +34 -8
- data/AGENTS.md +25 -0
- data/CHANGELOG.md +32 -24
- data/README.md +81 -57
- data/Rakefile +10 -3
- data/docs/raptor-vs-puma.md +4 -2
- data/docs/talk.md +1 -1
- data/lib/rackup/handler/raptor.rb +19 -12
- data/lib/raptor/binder.rb +17 -5
- data/lib/raptor/cli.rb +29 -2
- data/lib/raptor/cluster.rb +15 -130
- data/lib/raptor/embedded.rb +159 -0
- data/lib/raptor/reactor.rb +120 -73
- data/lib/raptor/version.rb +1 -1
- data/lib/raptor/worker.rb +200 -0
- data/lib/raptor.rb +1 -1
- data/sig/generated/rackup/handler/raptor.rbs +8 -8
- data/sig/generated/raptor/cli.rbs +5 -0
- data/sig/generated/raptor/cluster.rbs +8 -32
- data/sig/generated/raptor/embedded.rbs +68 -0
- data/sig/generated/raptor/reactor.rbs +31 -16
- data/sig/generated/raptor/worker.rbs +77 -0
- data/sig/generated/raptor.rbs +1 -1
- metadata +7 -2
data/lib/raptor/reactor.rb
CHANGED
|
@@ -9,7 +9,7 @@ require "atomic-ruby/atomic_boolean"
|
|
|
9
9
|
require "atomic-ruby/atomic_condition_variable"
|
|
10
10
|
require "atomic-ruby/atomic_queue"
|
|
11
11
|
require "atomic-ruby/atomic_thread_pool"
|
|
12
|
-
require "
|
|
12
|
+
require "io/event"
|
|
13
13
|
require "red-black-tree"
|
|
14
14
|
|
|
15
15
|
require_relative "detached_body"
|
|
@@ -76,7 +76,6 @@ module Raptor
|
|
|
76
76
|
attr_accessor :wait #: Symbol?
|
|
77
77
|
attr_accessor :reading #: bool
|
|
78
78
|
attr_accessor :closing #: bool
|
|
79
|
-
attr_accessor :monitor #: NIO::Monitor?
|
|
80
79
|
attr_accessor :timeout #: TimeoutClient?
|
|
81
80
|
attr_reader :output #: Array[String]
|
|
82
81
|
|
|
@@ -91,7 +90,6 @@ module Raptor
|
|
|
91
90
|
@wait = nil
|
|
92
91
|
@reading = false
|
|
93
92
|
@closing = false
|
|
94
|
-
@monitor = nil
|
|
95
93
|
@timeout = nil
|
|
96
94
|
end
|
|
97
95
|
|
|
@@ -182,7 +180,10 @@ module Raptor
|
|
|
182
180
|
# @rbs @persistent_data_timeout: Integer
|
|
183
181
|
# @rbs @http2_keepalive_interval: Integer
|
|
184
182
|
# @rbs @http2_keepalive_timeout: Integer
|
|
185
|
-
# @rbs @selector:
|
|
183
|
+
# @rbs @selector: untyped
|
|
184
|
+
# @rbs @wakeup: Fiber?
|
|
185
|
+
# @rbs @waiters: Hash[TCPSocket, [Fiber, Integer]]
|
|
186
|
+
# @rbs @ready: Array[[TCPSocket, Integer]]
|
|
186
187
|
# @rbs @queue: Queue[TCPSocket]
|
|
187
188
|
# @rbs @io_queue: AtomicQueue
|
|
188
189
|
# @rbs @io_applied: AtomicConditionVariable
|
|
@@ -231,7 +232,10 @@ module Raptor
|
|
|
231
232
|
@http2_keepalive_interval = http2_options[:keepalive_interval]
|
|
232
233
|
@http2_keepalive_timeout = http2_options[:keepalive_timeout]
|
|
233
234
|
|
|
234
|
-
@selector =
|
|
235
|
+
@selector = nil
|
|
236
|
+
@wakeup = nil
|
|
237
|
+
@waiters = {}
|
|
238
|
+
@ready = []
|
|
235
239
|
@queue = Queue.new
|
|
236
240
|
@io_queue = AtomicQueue.new
|
|
237
241
|
@io_applied = AtomicConditionVariable.new
|
|
@@ -259,16 +263,31 @@ module Raptor
|
|
|
259
263
|
#
|
|
260
264
|
# @rbs () -> Thread
|
|
261
265
|
def run
|
|
262
|
-
|
|
266
|
+
ready = AtomicConditionVariable.new
|
|
267
|
+
startup_error = nil
|
|
268
|
+
thread = Thread.new do
|
|
263
269
|
Thread.current.name = "Reactor"
|
|
264
270
|
@thread = Thread.current
|
|
271
|
+
begin
|
|
272
|
+
selector = IO::Event::Selector.new(Fiber.current)
|
|
273
|
+
@wakeup = Fiber.new { loop { selector.transfer } }
|
|
274
|
+
@selector = selector
|
|
275
|
+
rescue => error
|
|
276
|
+
startup_error = error
|
|
277
|
+
ready.signal
|
|
278
|
+
next
|
|
279
|
+
end
|
|
280
|
+
ready.signal
|
|
265
281
|
|
|
266
282
|
until stopped?
|
|
267
283
|
begin
|
|
268
284
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
269
285
|
timeout = @timeouts.min&.timeout(now)
|
|
270
|
-
@
|
|
271
|
-
|
|
286
|
+
timeout = 0 unless @ready.empty? && @queue.empty? && @io_queue.empty?
|
|
287
|
+
@selector.select(timeout)
|
|
288
|
+
until @ready.empty?
|
|
289
|
+
socket, events = @ready.shift
|
|
290
|
+
handle_ready(socket, events)
|
|
272
291
|
end
|
|
273
292
|
|
|
274
293
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
@@ -283,6 +302,8 @@ module Raptor
|
|
|
283
302
|
end
|
|
284
303
|
end
|
|
285
304
|
|
|
305
|
+
@waiters.keys.each { |socket| deregister(socket) }
|
|
306
|
+
@ready.clear
|
|
286
307
|
@id_to_flow_control.each_value(&:close)
|
|
287
308
|
@id_to_socket.each_value { |socket| socket.close rescue nil }
|
|
288
309
|
@id_to_socket.clear
|
|
@@ -298,6 +319,14 @@ module Raptor
|
|
|
298
319
|
@thread = nil
|
|
299
320
|
@selector.close
|
|
300
321
|
end
|
|
322
|
+
|
|
323
|
+
ready.wait { @selector || startup_error }
|
|
324
|
+
if startup_error
|
|
325
|
+
thread.join
|
|
326
|
+
raise startup_error
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
thread
|
|
301
330
|
end
|
|
302
331
|
|
|
303
332
|
# Adds a new client connection to the reactor.
|
|
@@ -330,7 +359,7 @@ module Raptor
|
|
|
330
359
|
|
|
331
360
|
@socket_to_state[socket] = state
|
|
332
361
|
@queue << socket
|
|
333
|
-
|
|
362
|
+
wakeup
|
|
334
363
|
rescue ClosedQueueError
|
|
335
364
|
socket.close
|
|
336
365
|
end
|
|
@@ -372,7 +401,7 @@ module Raptor
|
|
|
372
401
|
@id_to_socket[id] = socket
|
|
373
402
|
@socket_to_state[socket] = state
|
|
374
403
|
@queue << socket
|
|
375
|
-
|
|
404
|
+
wakeup
|
|
376
405
|
rescue ClosedQueueError
|
|
377
406
|
socket.close
|
|
378
407
|
end
|
|
@@ -422,7 +451,7 @@ module Raptor
|
|
|
422
451
|
def attach_http1_body(socket, id, body, state, finished)
|
|
423
452
|
attached = AtomicBoolean.new(false)
|
|
424
453
|
@io_queue << [:attach_http1, id, socket, body, attached, finished, state]
|
|
425
|
-
|
|
454
|
+
wakeup rescue nil
|
|
426
455
|
@io_applied.wait { attached.true? }
|
|
427
456
|
return false if body.closed?
|
|
428
457
|
|
|
@@ -430,7 +459,7 @@ module Raptor
|
|
|
430
459
|
true
|
|
431
460
|
rescue
|
|
432
461
|
@io_queue << [:cancel_http1, id]
|
|
433
|
-
|
|
462
|
+
wakeup rescue nil
|
|
434
463
|
raise
|
|
435
464
|
end
|
|
436
465
|
|
|
@@ -490,7 +519,7 @@ module Raptor
|
|
|
490
519
|
flush_output(id, io) if io && !io.wait
|
|
491
520
|
else
|
|
492
521
|
@io_queue << [:write, id, data]
|
|
493
|
-
|
|
522
|
+
wakeup rescue nil
|
|
494
523
|
end
|
|
495
524
|
end
|
|
496
525
|
|
|
@@ -506,7 +535,7 @@ module Raptor
|
|
|
506
535
|
def attach_http2_body(id, stream_id, body, finished)
|
|
507
536
|
attached = AtomicBoolean.new(false)
|
|
508
537
|
@io_queue << [:attach_http2, id, stream_id, body, attached, finished]
|
|
509
|
-
|
|
538
|
+
wakeup rescue nil
|
|
510
539
|
@io_applied.wait { attached.true? }
|
|
511
540
|
return false if body.closed?
|
|
512
541
|
|
|
@@ -527,7 +556,7 @@ module Raptor
|
|
|
527
556
|
return if @detached_count.value.zero?
|
|
528
557
|
|
|
529
558
|
@io_queue << [:resume_http2, id]
|
|
530
|
-
|
|
559
|
+
wakeup rescue nil
|
|
531
560
|
end
|
|
532
561
|
|
|
533
562
|
# Cancels a detached response stream.
|
|
@@ -541,7 +570,7 @@ module Raptor
|
|
|
541
570
|
return if @detached_count.value.zero?
|
|
542
571
|
|
|
543
572
|
@io_queue << [:cancel_http2, id, stream_id]
|
|
544
|
-
|
|
573
|
+
wakeup rescue nil
|
|
545
574
|
end
|
|
546
575
|
|
|
547
576
|
# Waits for detached responses to finish, then cancels any that outlive
|
|
@@ -554,7 +583,7 @@ module Raptor
|
|
|
554
583
|
def drain_detached_bodies(timeout)
|
|
555
584
|
barrier = AtomicBoolean.new(false)
|
|
556
585
|
@io_queue << [:barrier, nil, barrier]
|
|
557
|
-
|
|
586
|
+
wakeup rescue nil
|
|
558
587
|
@io_applied.wait { barrier.true? }
|
|
559
588
|
|
|
560
589
|
Timeout.timeout(timeout) do
|
|
@@ -562,7 +591,7 @@ module Raptor
|
|
|
562
591
|
end
|
|
563
592
|
rescue Timeout::Error
|
|
564
593
|
@io_queue << [:cancel_all]
|
|
565
|
-
|
|
594
|
+
wakeup rescue nil
|
|
566
595
|
@detached_drained.wait { @detached_count.value.zero? }
|
|
567
596
|
end
|
|
568
597
|
|
|
@@ -617,7 +646,7 @@ module Raptor
|
|
|
617
646
|
return unless socket
|
|
618
647
|
|
|
619
648
|
@queue << socket
|
|
620
|
-
|
|
649
|
+
wakeup
|
|
621
650
|
rescue ClosedQueueError
|
|
622
651
|
socket.close
|
|
623
652
|
end
|
|
@@ -630,7 +659,7 @@ module Raptor
|
|
|
630
659
|
# @rbs (Integer id) -> void
|
|
631
660
|
def close_connection(id)
|
|
632
661
|
@io_queue << [:close, id]
|
|
633
|
-
|
|
662
|
+
wakeup rescue nil
|
|
634
663
|
end
|
|
635
664
|
|
|
636
665
|
# Closes the registration queue and wakes the selector so the
|
|
@@ -641,7 +670,7 @@ module Raptor
|
|
|
641
670
|
# @rbs () -> void
|
|
642
671
|
def shutdown
|
|
643
672
|
@queue.close
|
|
644
|
-
|
|
673
|
+
wakeup
|
|
645
674
|
end
|
|
646
675
|
|
|
647
676
|
# Returns the number of complete requests either being processed
|
|
@@ -656,6 +685,17 @@ module Raptor
|
|
|
656
685
|
|
|
657
686
|
private
|
|
658
687
|
|
|
688
|
+
# Wakes the event loop, including work queued before it starts waiting.
|
|
689
|
+
#
|
|
690
|
+
# @rbs () -> void
|
|
691
|
+
def wakeup
|
|
692
|
+
selector = @selector
|
|
693
|
+
return unless selector
|
|
694
|
+
|
|
695
|
+
selector.push(@wakeup)
|
|
696
|
+
selector.wakeup
|
|
697
|
+
end
|
|
698
|
+
|
|
659
699
|
# Returns whether shutdown has no registrations or writes left to drain.
|
|
660
700
|
#
|
|
661
701
|
# @return [Boolean]
|
|
@@ -760,7 +800,7 @@ module Raptor
|
|
|
760
800
|
dispatch = proc { |callback| @thread_pool << callback }
|
|
761
801
|
wake = proc do
|
|
762
802
|
@io_queue << [:ready_http1, id]
|
|
763
|
-
|
|
803
|
+
wakeup rescue nil
|
|
764
804
|
end
|
|
765
805
|
unless body.attach([io.budget, @detached_budget], wake, dispatch, finished)
|
|
766
806
|
socket.close rescue nil
|
|
@@ -771,7 +811,7 @@ module Raptor
|
|
|
771
811
|
@socket_to_state[socket] = { id: id, protocol: :http1, detached: true }
|
|
772
812
|
@id_to_io[id] = io
|
|
773
813
|
@detached_count.swap { |count| count + 1 }
|
|
774
|
-
|
|
814
|
+
update_interests(id, io)
|
|
775
815
|
end
|
|
776
816
|
|
|
777
817
|
# Writes buffered HTTP/1.x body chunks without blocking.
|
|
@@ -803,7 +843,7 @@ module Raptor
|
|
|
803
843
|
|
|
804
844
|
if !io.finishing && !io.wait && io.body&.next_size
|
|
805
845
|
@io_queue << [:ready_http1, id]
|
|
806
|
-
|
|
846
|
+
wakeup rescue nil
|
|
807
847
|
end
|
|
808
848
|
end
|
|
809
849
|
|
|
@@ -823,7 +863,7 @@ module Raptor
|
|
|
823
863
|
body.finish(:closed)
|
|
824
864
|
detached_body_removed
|
|
825
865
|
@id_to_io.delete(id)
|
|
826
|
-
deregister(socket
|
|
866
|
+
deregister(socket)
|
|
827
867
|
clear_write_timeout(io)
|
|
828
868
|
|
|
829
869
|
if io.state[:keep_alive]
|
|
@@ -887,7 +927,7 @@ module Raptor
|
|
|
887
927
|
|
|
888
928
|
wake = proc do
|
|
889
929
|
@io_queue << [:ready_http2, id, stream_id]
|
|
890
|
-
|
|
930
|
+
wakeup rescue nil
|
|
891
931
|
end
|
|
892
932
|
return unless body.attach([io.budget, @detached_budget], wake, dispatch, finished)
|
|
893
933
|
|
|
@@ -967,7 +1007,7 @@ module Raptor
|
|
|
967
1007
|
|
|
968
1008
|
if !io.wait && io.output.empty? && !io.ready.empty?
|
|
969
1009
|
@io_queue << [:flush_http2, id]
|
|
970
|
-
|
|
1010
|
+
wakeup rescue nil
|
|
971
1011
|
end
|
|
972
1012
|
end
|
|
973
1013
|
|
|
@@ -1133,7 +1173,7 @@ module Raptor
|
|
|
1133
1173
|
elsif io.closing
|
|
1134
1174
|
remove_connection(id)
|
|
1135
1175
|
else
|
|
1136
|
-
|
|
1176
|
+
update_interests(id, io)
|
|
1137
1177
|
end
|
|
1138
1178
|
end
|
|
1139
1179
|
|
|
@@ -1148,7 +1188,7 @@ module Raptor
|
|
|
1148
1188
|
def wait_for_write(id, io, readiness)
|
|
1149
1189
|
io.wait = readiness
|
|
1150
1190
|
track_write_timeout(id, io)
|
|
1151
|
-
|
|
1191
|
+
update_interests(id, io)
|
|
1152
1192
|
end
|
|
1153
1193
|
|
|
1154
1194
|
# Updates selector interest for one reactor-owned connection.
|
|
@@ -1158,26 +1198,34 @@ module Raptor
|
|
|
1158
1198
|
# @return [void]
|
|
1159
1199
|
#
|
|
1160
1200
|
# @rbs (Integer id, ConnectionIO io) -> void
|
|
1161
|
-
def
|
|
1201
|
+
def update_interests(id, io)
|
|
1162
1202
|
socket = @id_to_socket[id]
|
|
1163
1203
|
return unless socket && io
|
|
1164
1204
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1205
|
+
events = 0
|
|
1206
|
+
events |= IO::READABLE if io.reading || io.wait == :read
|
|
1207
|
+
events |= IO::WRITABLE if io.wait == :write
|
|
1208
|
+
wait_for_io(socket, events)
|
|
1209
|
+
end
|
|
1210
|
+
|
|
1211
|
+
# Waits for a connection's next readable or writable event.
|
|
1212
|
+
#
|
|
1213
|
+
# @rbs (TCPSocket socket, Integer events) -> void
|
|
1214
|
+
def wait_for_io(socket, events)
|
|
1215
|
+
waiter = @waiters[socket]
|
|
1216
|
+
return if waiter && waiter[1] == events
|
|
1174
1217
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1218
|
+
deregister(socket)
|
|
1219
|
+
return if events.zero?
|
|
1220
|
+
|
|
1221
|
+
fiber = Fiber.new do
|
|
1222
|
+
readiness = @selector.io_wait(Fiber.current, socket, events)
|
|
1223
|
+
@ready << [socket, readiness] if readiness
|
|
1224
|
+
ensure
|
|
1225
|
+
@waiters.delete(socket)
|
|
1180
1226
|
end
|
|
1227
|
+
@waiters[socket] = [fiber, events]
|
|
1228
|
+
fiber.transfer
|
|
1181
1229
|
end
|
|
1182
1230
|
|
|
1183
1231
|
# Starts or refreshes one connection's non-blocking write deadline.
|
|
@@ -1210,19 +1258,15 @@ module Raptor
|
|
|
1210
1258
|
# Removes a socket from selector tracking.
|
|
1211
1259
|
#
|
|
1212
1260
|
# @param socket [TCPSocket] socket to deregister
|
|
1213
|
-
# @param io [ConnectionIO, nil] connection I/O state
|
|
1214
1261
|
# @return [void]
|
|
1215
1262
|
#
|
|
1216
|
-
# @rbs (TCPSocket socket
|
|
1217
|
-
def deregister(socket
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
@selector.deregister(socket)
|
|
1221
|
-
io.monitor = nil if io
|
|
1222
|
-
rescue IOError
|
|
1263
|
+
# @rbs (TCPSocket socket) -> void
|
|
1264
|
+
def deregister(socket)
|
|
1265
|
+
waiter = @waiters.delete(socket)
|
|
1266
|
+
waiter[0].transfer if waiter
|
|
1223
1267
|
end
|
|
1224
1268
|
|
|
1225
|
-
# Registers a socket
|
|
1269
|
+
# Registers a socket for readiness and sets up timeout tracking.
|
|
1226
1270
|
#
|
|
1227
1271
|
# @param socket [TCPSocket] the socket to register
|
|
1228
1272
|
# @return [void]
|
|
@@ -1235,9 +1279,9 @@ module Raptor
|
|
|
1235
1279
|
if state[:protocol] == :http2
|
|
1236
1280
|
io = @id_to_io[state[:id]]
|
|
1237
1281
|
io.reading = true
|
|
1238
|
-
|
|
1282
|
+
update_interests(state[:id], io)
|
|
1239
1283
|
else
|
|
1240
|
-
|
|
1284
|
+
wait_for_io(socket, IO::READABLE)
|
|
1241
1285
|
end
|
|
1242
1286
|
|
|
1243
1287
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
@@ -1301,17 +1345,17 @@ module Raptor
|
|
|
1301
1345
|
# Dispatches readable and writable events without allowing application
|
|
1302
1346
|
# threads to take ownership of HTTP/2 sockets.
|
|
1303
1347
|
#
|
|
1304
|
-
# @param
|
|
1348
|
+
# @param socket [TCPSocket] ready client socket
|
|
1349
|
+
# @param events [Integer] readiness events
|
|
1305
1350
|
# @return [void]
|
|
1306
1351
|
#
|
|
1307
|
-
# @rbs (
|
|
1308
|
-
def
|
|
1309
|
-
socket = monitor.value
|
|
1352
|
+
# @rbs (TCPSocket socket, Integer events) -> void
|
|
1353
|
+
def handle_ready(socket, events)
|
|
1310
1354
|
state = @socket_to_state[socket]
|
|
1311
1355
|
return unless state
|
|
1312
1356
|
|
|
1313
1357
|
if state[:detached]
|
|
1314
|
-
|
|
1358
|
+
handle_http1_detached_ready(socket, events, state[:id])
|
|
1315
1359
|
return
|
|
1316
1360
|
end
|
|
1317
1361
|
|
|
@@ -1325,7 +1369,7 @@ module Raptor
|
|
|
1325
1369
|
return unless io
|
|
1326
1370
|
|
|
1327
1371
|
wait = io.wait
|
|
1328
|
-
if (wait == :read &&
|
|
1372
|
+
if (wait == :read && events.anybits?(IO::READABLE)) || (wait == :write && events.anybits?(IO::WRITABLE))
|
|
1329
1373
|
flush_output(id, io)
|
|
1330
1374
|
return unless @id_to_socket.key?(id)
|
|
1331
1375
|
return if io.wait == :read
|
|
@@ -1333,40 +1377,43 @@ module Raptor
|
|
|
1333
1377
|
flush_http2_detached_bodies(id) unless io.detached.empty?
|
|
1334
1378
|
end
|
|
1335
1379
|
|
|
1336
|
-
return unless io.reading &&
|
|
1380
|
+
return unless io.reading && events.anybits?(IO::READABLE)
|
|
1337
1381
|
|
|
1338
1382
|
io.reading = false
|
|
1339
|
-
|
|
1383
|
+
update_interests(id, io)
|
|
1340
1384
|
client = @id_to_timeout.delete(id)
|
|
1341
1385
|
@timeouts.delete!(client) if client
|
|
1342
1386
|
read_and_queue_for_parse(socket, state)
|
|
1387
|
+
ensure
|
|
1388
|
+
io = @id_to_io[state[:id]] if state
|
|
1389
|
+
update_interests(state[:id], io) if io
|
|
1343
1390
|
end
|
|
1344
1391
|
|
|
1345
1392
|
# Handles readiness for an HTTP/1.x detached response.
|
|
1346
1393
|
#
|
|
1347
|
-
# @param
|
|
1394
|
+
# @param socket [TCPSocket] ready client socket
|
|
1395
|
+
# @param events [Integer] readiness events
|
|
1348
1396
|
# @param id [Integer] unique connection identifier
|
|
1349
1397
|
# @return [void]
|
|
1350
1398
|
#
|
|
1351
|
-
# @rbs (
|
|
1352
|
-
def
|
|
1353
|
-
socket = monitor.value
|
|
1399
|
+
# @rbs (TCPSocket socket, Integer events, Integer id) -> void
|
|
1400
|
+
def handle_http1_detached_ready(socket, events, id)
|
|
1354
1401
|
io = @id_to_io[id]
|
|
1355
1402
|
return unless io.is_a?(Http1IO)
|
|
1356
1403
|
|
|
1357
1404
|
wait = io.wait
|
|
1358
|
-
if (wait == :read &&
|
|
1405
|
+
if (wait == :read && events.anybits?(IO::READABLE)) || (wait == :write && events.anybits?(IO::WRITABLE))
|
|
1359
1406
|
flush_output(id, io)
|
|
1360
1407
|
return unless @id_to_io.key?(id)
|
|
1361
1408
|
|
|
1362
1409
|
flush_http1_detached_body(id) unless io.wait
|
|
1363
1410
|
end
|
|
1364
1411
|
|
|
1365
|
-
return unless io.reading &&
|
|
1412
|
+
return unless io.reading && events.anybits?(IO::READABLE)
|
|
1366
1413
|
|
|
1367
1414
|
io.input << socket.read_nonblock(CHUNK_SIZE)
|
|
1368
1415
|
io.reading = false
|
|
1369
|
-
|
|
1416
|
+
update_interests(id, io)
|
|
1370
1417
|
rescue IO::WaitReadable
|
|
1371
1418
|
rescue IO::WaitWritable
|
|
1372
1419
|
wait_for_write(id, io, :write)
|
|
@@ -1382,7 +1429,7 @@ module Raptor
|
|
|
1382
1429
|
#
|
|
1383
1430
|
# @rbs (TCPSocket socket) -> void
|
|
1384
1431
|
def wakeup!(socket)
|
|
1385
|
-
|
|
1432
|
+
deregister(socket)
|
|
1386
1433
|
state = @socket_to_state[socket]
|
|
1387
1434
|
client = @id_to_timeout.delete(state[:id])
|
|
1388
1435
|
@timeouts.delete!(client) if client
|
|
@@ -1433,7 +1480,7 @@ module Raptor
|
|
|
1433
1480
|
socket.read_nonblock(CHUNK_SIZE)
|
|
1434
1481
|
rescue IO::WaitReadable
|
|
1435
1482
|
@queue << socket
|
|
1436
|
-
|
|
1483
|
+
wakeup
|
|
1437
1484
|
return
|
|
1438
1485
|
rescue EOFError, IOError, SystemCallError, OpenSSL::SSL::SSLError
|
|
1439
1486
|
cleanup(socket)
|
|
@@ -1461,7 +1508,7 @@ module Raptor
|
|
|
1461
1508
|
def cleanup(socket)
|
|
1462
1509
|
state = @socket_to_state.delete(socket)
|
|
1463
1510
|
io = @id_to_io.delete(state[:id])
|
|
1464
|
-
deregister(socket
|
|
1511
|
+
deregister(socket)
|
|
1465
1512
|
@id_to_socket.delete(state[:id])
|
|
1466
1513
|
@id_to_writer.delete(state[:id])
|
|
1467
1514
|
@id_to_flow_control.delete(state[:id])&.close
|
data/lib/raptor/version.rb
CHANGED