Skip to content

Commit eba6df3

Browse files
committed
Code review
1 parent 49bd911 commit eba6df3

File tree

2 files changed

+61
-79
lines changed

2 files changed

+61
-79
lines changed

Sources/AsyncHTTPClient/ConnectionPool/HTTPRequestStateMachine.swift

Lines changed: 40 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ struct HTTPRequestStateMachine {
5454
}
5555

5656
/// The request is streaming its request body. `expectedBodyLength` has a value, if the request header contained
57-
/// a `"content-length"` header field. It is the request header contained a `"transfer-encoding" = "chunked"`
58-
/// header field.
57+
/// a `"content-length"` header field. If the request header contained a `"transfer-encoding" = "chunked"`
58+
/// header field, the `expectedBodyLength` is `nil`.
5959
case streaming(expectedBodyLength: Int?, sentBodyBytes: Int, producer: ProducerControlState)
6060
/// The request has sent its request body and end.
6161
case endSent
@@ -73,35 +73,36 @@ struct HTTPRequestStateMachine {
7373
case waitingForHead
7474
/// A response head has been received and we are ready to consume more data off the wire
7575
case receivingBody(HTTPResponseHead, ConsumerControlState)
76-
/// A response end has been received and we are ready to consume more data of the wire
76+
/// A response end has been received. We don't expect more bytes from the wire.
7777
case endReceived
7878
}
7979

8080
enum Action {
8181
/// A action to execute, when we consider a request "done".
8282
enum FinalStreamAction {
83-
/// close the connection
83+
/// Close the connection
8484
case close
85-
/// trigger a read event
85+
/// Trigger a read event
8686
case read
87-
/// do nothing
87+
/// Do nothing. This is action is used, if the request failed, before we the request head was written onto the wire.
88+
/// This might happen if the request is cancelled, or the request failed the soundness check.
8889
case none
8990
}
9091

9192
case verifyRequest
9293

93-
case sendRequestHead(HTTPRequestHead, startBody: Bool, startReadTimeoutTimer: TimeAmount?)
94+
case sendRequestHead(HTTPRequestHead, startBody: Bool)
9495
case sendBodyPart(IOData)
95-
case sendRequestEnd(startReadTimeoutTimer: TimeAmount?)
96+
case sendRequestEnd
9697

9798
case pauseRequestBodyStream
9899
case resumeRequestBodyStream
99100

100101
case forwardResponseHead(HTTPResponseHead, pauseRequestBodyStream: Bool)
101-
case forwardResponseBodyPart(ByteBuffer, resetReadTimeoutTimer: TimeAmount?)
102+
case forwardResponseBodyPart(ByteBuffer)
102103

103-
case failRequest(Error, FinalStreamAction, clearReadTimeoutTimer: Bool)
104-
case succeedRequest(FinalStreamAction, clearReadTimeoutTimer: Bool)
104+
case failRequest(Error, FinalStreamAction)
105+
case succeedRequest(FinalStreamAction)
105106

106107
case read
107108
case wait
@@ -207,8 +208,10 @@ struct HTTPRequestStateMachine {
207208
case .running(let requestState, .receivingBody(let responseHead, .downstreamIsConsuming(readPending: false))):
208209
self.state = .running(requestState, .receivingBody(responseHead, .downstreamIsConsuming(readPending: true)))
209210
return .wait
210-
case .running(let requestState, .receivingBody(let responseHead, .downstreamHasDemand)):
211-
self.state = .running(requestState, .receivingBody(responseHead, .downstreamHasDemand))
211+
case .running(_, .receivingBody(_, .downstreamHasDemand)):
212+
// The consumer has signaled a demand for more response body bytes. If a `read` is
213+
// caught, we pass it on right away. The state machines does not transition into another
214+
// state.
212215
return .read
213216
}
214217
}
@@ -220,10 +223,10 @@ struct HTTPRequestStateMachine {
220223
case .verifyingRequest, .waitForChannelToBecomeWritable:
221224
// the request failed, before it was sent onto the wire.
222225
self.state = .failed(error)
223-
return .failRequest(error, .none, clearReadTimeoutTimer: false)
226+
return .failRequest(error, .none)
224227
case .running:
225228
self.state = .failed(error)
226-
return .failRequest(error, .close, clearReadTimeoutTimer: false)
229+
return .failRequest(error, .close)
227230
case .finished, .failed:
228231
preconditionFailure("If the request is finished or failed, we expect the connection state machine to remove the request immediately from its state. Thus this state is unreachable.")
229232
}
@@ -269,17 +272,10 @@ struct HTTPRequestStateMachine {
269272
// pause. The reason for this is as follows: There might be thread synchronization
270273
// situations in which the producer might not have received the plea to pause yet.
271274

272-
if let expected = expectedBodyLength {
273-
if sentBodyBytes + part.readableBytes > expected {
274-
let error = HTTPClientError.bodyLengthMismatch
275-
276-
var clearReadTimeoutTimer = false
277-
if case .receivingBody = responseState, self.idleReadTimeout != nil {
278-
clearReadTimeoutTimer = true
279-
}
275+
if let expected = expectedBodyLength, sentBodyBytes + part.readableBytes > expected {
276+
let error = HTTPClientError.bodyLengthMismatch
280277

281-
return .failRequest(error, .close, clearReadTimeoutTimer: clearReadTimeoutTimer)
282-
}
278+
return .failRequest(error, .close)
283279
}
284280

285281
sentBodyBytes += part.readableBytes
@@ -324,33 +320,33 @@ struct HTTPRequestStateMachine {
324320
if let expected = expectedBodyLength, expected != sentBodyBytes {
325321
let error = HTTPClientError.bodyLengthMismatch
326322
self.state = .failed(error)
327-
return .failRequest(error, .close, clearReadTimeoutTimer: false)
323+
return .failRequest(error, .close)
328324
}
329325

330326
self.state = .running(.endSent, .waitingForHead)
331-
return .sendRequestEnd(startReadTimeoutTimer: self.idleReadTimeout)
327+
return .sendRequestEnd
332328

333329
case .running(.streaming(let expectedBodyLength, let sentBodyBytes, _), .receivingBody(let head, let streamState)):
334330
assert(head.status.code < 300)
335331

336332
if let expected = expectedBodyLength, expected != sentBodyBytes {
337333
let error = HTTPClientError.bodyLengthMismatch
338334
self.state = .failed(error)
339-
return .failRequest(error, .close, clearReadTimeoutTimer: self.idleReadTimeout != nil)
335+
return .failRequest(error, .close)
340336
}
341337

342338
self.state = .running(.endSent, .receivingBody(head, streamState))
343-
return .sendRequestEnd(startReadTimeoutTimer: self.idleReadTimeout)
339+
return .sendRequestEnd
344340

345341
case .running(.streaming(let expectedBodyLength, let sentBodyBytes, _), .endReceived):
346342
if let expected = expectedBodyLength, expected != sentBodyBytes {
347343
let error = HTTPClientError.bodyLengthMismatch
348344
self.state = .failed(error)
349-
return .failRequest(error, .close, clearReadTimeoutTimer: false)
345+
return .failRequest(error, .close)
350346
}
351347

352348
self.state = .finished
353-
return .succeedRequest(.none, clearReadTimeoutTimer: false)
349+
return .succeedRequest(.none)
354350

355351
case .failed:
356352
return .wait
@@ -362,16 +358,11 @@ struct HTTPRequestStateMachine {
362358
case .initialized, .verifyingRequest, .waitForChannelToBecomeWritable:
363359
let error = HTTPClientError.cancelled
364360
self.state = .failed(error)
365-
return .failRequest(error, .none, clearReadTimeoutTimer: false)
366-
case .running(_, let responseState):
361+
return .failRequest(error, .none)
362+
case .running:
367363
let error = HTTPClientError.cancelled
368364
self.state = .failed(error)
369-
370-
var clearReadTimeoutTimer = false
371-
if case .receivingBody = responseState, self.idleReadTimeout != nil {
372-
clearReadTimeoutTimer = true
373-
}
374-
return .failRequest(error, .close, clearReadTimeoutTimer: clearReadTimeoutTimer)
365+
return .failRequest(error, .close)
375366
case .finished:
376367
return .wait
377368
case .failed:
@@ -381,19 +372,10 @@ struct HTTPRequestStateMachine {
381372

382373
mutating func channelInactive() -> Action {
383374
switch self.state {
384-
case .initialized, .verifyingRequest, .waitForChannelToBecomeWritable:
385-
let error = HTTPClientError.remoteConnectionClosed
386-
self.state = .failed(error)
387-
return .failRequest(error, .none, clearReadTimeoutTimer: false)
388-
case .running(_, let responseState):
375+
case .initialized, .verifyingRequest, .waitForChannelToBecomeWritable, .running:
389376
let error = HTTPClientError.remoteConnectionClosed
390377
self.state = .failed(error)
391-
392-
var clearReadTimeoutTimer = false
393-
if case .receivingBody = responseState, self.idleReadTimeout != nil {
394-
clearReadTimeoutTimer = true
395-
}
396-
return .failRequest(error, .none, clearReadTimeoutTimer: clearReadTimeoutTimer)
378+
return .failRequest(error, .none)
397379
case .finished:
398380
return .wait
399381
case .failed:
@@ -457,12 +439,12 @@ struct HTTPRequestStateMachine {
457439

458440
case .running(let requestState, .receivingBody(let head, .downstreamHasDemand)):
459441
self.state = .running(requestState, .receivingBody(head, .downstreamIsConsuming(readPending: false)))
460-
return .forwardResponseBodyPart(body, resetReadTimeoutTimer: self.idleReadTimeout)
442+
return .forwardResponseBodyPart(body)
461443

462444
case .running(_, .receivingBody(_, .downstreamIsConsuming)):
463445
// the state doesn't need to be changed. we are already in the correct state.
464446
// just forward the data.
465-
return .forwardResponseBodyPart(body, resetReadTimeoutTimer: self.idleReadTimeout)
447+
return .forwardResponseBodyPart(body)
466448

467449
case .running(_, .endReceived), .finished:
468450
preconditionFailure("How can we successfully finish the request, before having received a head. Invalid state: \(self.state)")
@@ -490,7 +472,7 @@ struct HTTPRequestStateMachine {
490472
assert(head.status.code >= 300)
491473
assert(producerState == .paused, "Expected to have paused the request body stream, when the head was received. Invalid state: \(self.state)")
492474
self.state = .finished
493-
return .succeedRequest(.close, clearReadTimeoutTimer: self.idleReadTimeout != nil)
475+
return .succeedRequest(.close)
494476

495477
case .running(.endSent, .receivingBody(_, let streamState)):
496478
let finalAction: Action.FinalStreamAction
@@ -502,7 +484,7 @@ struct HTTPRequestStateMachine {
502484
}
503485

504486
self.state = .finished
505-
return .succeedRequest(finalAction, clearReadTimeoutTimer: self.idleReadTimeout != nil)
487+
return .succeedRequest(finalAction)
506488

507489
case .running(_, .endReceived), .finished:
508490
preconditionFailure("How can we receive a response end, if another one was already received. Invalid state: \(self.state)")
@@ -546,7 +528,7 @@ struct HTTPRequestStateMachine {
546528
case .running(.endSent, .waitingForHead), .running(.endSent, .receivingBody):
547529
let error = HTTPClientError.readTimeout
548530
self.state = .failed(error)
549-
return .failRequest(error, .close, clearReadTimeoutTimer: false)
531+
return .failRequest(error, .close)
550532

551533
case .running(.endSent, .endReceived):
552534
preconditionFailure("Invalid state. This state should be: .finished")
@@ -559,13 +541,13 @@ struct HTTPRequestStateMachine {
559541
private mutating func startSendingRequestHead(_ head: HTTPRequestHead) -> Action {
560542
if let value = head.headers.first(name: "content-length"), let length = Int(value), length > 0 {
561543
self.state = .running(.streaming(expectedBodyLength: length, sentBodyBytes: 0, producer: .producing), .waitingForHead)
562-
return .sendRequestHead(head, startBody: true, startReadTimeoutTimer: nil)
544+
return .sendRequestHead(head, startBody: true)
563545
} else if head.headers.contains(name: "transfer-encoding") {
564546
self.state = .running(.streaming(expectedBodyLength: nil, sentBodyBytes: 0, producer: .producing), .waitingForHead)
565-
return .sendRequestHead(head, startBody: true, startReadTimeoutTimer: nil)
547+
return .sendRequestHead(head, startBody: true)
566548
} else {
567549
self.state = .running(.endSent, .waitingForHead)
568-
return .sendRequestHead(head, startBody: false, startReadTimeoutTimer: self.idleReadTimeout)
550+
return .sendRequestHead(head, startBody: false)
569551
}
570552
}
571553
}

0 commit comments

Comments
 (0)