Skip to content

Conversation

@fabianfett
Copy link
Member

@fabianfettfabianfett commented Jul 6, 2021

Motivation

After a lengthy offline discussion @Lukasa, we concluded that it would be best, if the HTTPRequestStateMachine would buffer up all reads until the next channelReadComplete. The main reason is, we minimize potential cross thread communication, by passing collected byteBuffers onward.

Modifications

  • ConsumerControlState was replaced with ResponseStreamState
  • channelReads are buffered up to a channelReadComplete.
  • on channelReadComplete all buffered body parts are forwarded to the consumer

@fabianfettfabianfett requested a review from LukasaJuly 6, 2021 14:14
@fabianfettfabianfett added the 🔨 semver/patch No public API change. label Jul 6, 2021
@fabianfettfabianfett added this to the HTTP/2 support milestone Jul 6, 2021
case waitingForRead(CircularBuffer<ByteBuffer>)
/// The state machines expects a call to `demandMoreResponseBodyParts`. The buffer is empty. It is
/// preserved for performance reasons.
case waitingForDemand(CircularBuffer<ByteBuffer>)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By making this a mini-state-machine, I recommend going the whole way: pull this out to a file and give it a bunch of methods that correspond to the events that can occur to it (e.g. func read). Then, the bigger state machine can just call those.

@fabianfettfabianfettforce-pushed the ff-buffer-in-channel branch from d76029f to 96fbbbdCompareJuly 6, 2021 16:08
@fabianfettfabianfett changed the title Buffer channelReads in the HTTPRequestStateMachine until the next channelReadCompleteBuffer channelReads in ResponseStreamState until the next channelReadCompleteJul 6, 2021
privatevarstate:State

init(expectingBody:Bool){
self.state =.waitingForBytes(CircularBuffer(initialCapacity: expectingBody ?16:0))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that there is no such thing as an empty circular buffer (initialCapacity: 0 still allocates) we may as well skip the branch and just always set 16.

mutatingfunc end()->CircularBuffer<ByteBuffer>{
switchself.state {
case.waitingForBytes(let buffer):
// This should never happen. But we don't want to precondition this behavior. Let's just
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is wrong.

expectingBody =true
}
}elseif head.headers.contains(name:"transfer-encoding"){
expectingBody =true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can delete this code per my above comment.

@fabianfettfabianfettforce-pushed the ff-buffer-in-channel branch from 2c49141 to a4fba69CompareJuly 7, 2021 10:52
@fabianfettfabianfett merged commit fcb0f21 into swift-server:mainJul 7, 2021
@fabianfettfabianfett deleted the ff-buffer-in-channel branch July 7, 2021 11:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patchNo public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@fabianfett@Lukasa