Skip to content

Commit 69539a0

Browse files
committed
Final read events
1 parent 650d14b commit 69539a0

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

Sources/AsyncHTTPClient/ConnectionPool/HTTPRequestStateMachine.swift

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ struct HTTPRequestStateMachine {
6161
/// A sub state for receiving a response. Stores whether the consumer has either signaled demand for more data or
6262
/// is busy consuming the so far forwarded bytes
6363
enum ConsumerControlState {
64+
/// the state machine is in this state once it has passed down a request head or body part. If a read event
65+
/// occurs while in this state, the readPending flag will be set true. If the consumer signals more demand
66+
/// by invoking `forwardMoreBodyParts`, the state machine will forward the read event.
6467
case downstreamIsConsuming(readPending: Bool)
68+
/// the state machine is in this state once the consumer has signaled more demand by invoking
69+
/// `forwardMoreBodyParts`. If a read event occurs in this state the read event will be forwarded
70+
/// immediately.
6571
case downstreamHasDemand
6672
}
6773

@@ -457,17 +463,20 @@ struct HTTPRequestStateMachine {
457463
self.state = .finished
458464
return .succeedRequest(.close)
459465

460-
case .running(.endSent, .receivingBody(_, let streamState)):
461-
let finalAction: Action.FinalStreamAction
462-
switch streamState {
463-
case .downstreamIsConsuming(readPending: true):
464-
finalAction = .read
465-
case .downstreamIsConsuming(readPending: false), .downstreamHasDemand:
466-
finalAction = .none
467-
}
466+
case .running(.endSent, .receivingBody(_, .downstreamIsConsuming(readPending: true))):
467+
// If we have a received a read event before, we must ensure that the read event
468+
// eventually gets onto the channel pipeline again. The end of the request gives
469+
// us an opportunity for this clean up task.
470+
// It is very unlikely that we can see this in the real world. If we have swallowed
471+
// a read event we don't expect to receive further data from the channel incl.
472+
// response ends.
473+
self.state = .finished
474+
return .succeedRequest(.read)
468475

476+
case .running(.endSent, .receivingBody(_, .downstreamIsConsuming(readPending: false))),
477+
.running(.endSent, .receivingBody(_, .downstreamHasDemand)):
469478
self.state = .finished
470-
return .succeedRequest(finalAction)
479+
return .succeedRequest(.none)
471480

472481
case .running(_, .endReceived), .finished:
473482
preconditionFailure("How can we receive a response end, if another one was already received. Invalid state: \(self.state)")

0 commit comments

Comments
 (0)