Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.x.x - Wrap InboundStream iterator in request body #369

Merged
merged 8 commits into from
Feb 5, 2024

Conversation

adam-fowler
Copy link
Member

@adam-fowler adam-fowler commented Feb 1, 2024

Wrap NIOAsyncChannelInboundStream.Iterator in request body in another AsyncSequence. This removes the creation of an AsyncChannel and gets rid of a TaskGroup. Performance improvement is about 12%.

Issues:

  • It isn't currently possible to create NIOAsyncChannelInboundStream outside of a channel or for testing, so editing the request body in middleware won't be possible unless I'm happy to use some form of AnyAsyncSequence for the request body.
  • If a user attempts to parse the request body AsyncSequence twice, the second time they'll start reading the next request. I could avoid this by making HBStreamedRequestBody a reference type and writing back into it that the sequence is done once the first iteration is done and not allow another iteration. This complicated the flush request body code at the end of the loop.

EDIT:

  • I've now made HBStreamedRequestBody a reference type so we can record if an iterator has already been created from it. This resolves my second issue. This reduces the performance gain to about 10-11%
  • I've also added in a conversion from ByteBuffer back to AsyncSequence using the makeTestingStream. I know this uses AsyncStream internally which has back pressure issues but I only stick one ByteBuffer on it and then finish it.

cc @FranzBusch

Copy link

codecov bot commented Feb 1, 2024

Codecov Report

Attention: 8 lines in your changes are missing coverage. Please review.

Comparison is base (4a2a119) 84.07% compared to head (f7089bb) 84.44%.
Report is 1 commits behind head on 2.x.x.

Files Patch % Lines
Sources/HummingbirdCore/Request/RequestBody.swift 96.66% 4 Missing ⚠️
Sources/HummingbirdCore/Utils/UnsafeTransfer.swift 50.00% 3 Missing ⚠️
...mmingbirdCore/Server/HTTP/HTTPChannelHandler.swift 98.14% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            2.x.x     #369      +/-   ##
==========================================
+ Coverage   84.07%   84.44%   +0.36%     
==========================================
  Files          93       95       +2     
  Lines        5099     5207     +108     
==========================================
+ Hits         4287     4397     +110     
+ Misses        812      810       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

github-actions bot commented Feb 1, 2024

@adam-fowler adam-fowler requested a review from Joannis February 1, 2024 17:46
public struct HBStreamedRequestBody: Sendable, AsyncSequence {
public typealias Element = ByteBuffer
public typealias InboundStream = NIOAsyncChannelInboundStream<HTTPRequestPart>
Copy link
Member

Choose a reason for hiding this comment

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

We should prevent exposing this type, as we're locking ourselves in a corner

Copy link
Member Author

Choose a reason for hiding this comment

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

At some point we are going to have to expose a public way to create a HBRequestBody that is initialised with a stream of data and at that time we'll have to expose the internal type to avoid having to do type conversions.

* Use AnyAsyncSequence to hold request body async sequence

* Make contents of HBRequestBody internal

* Remove HBRequestBody.collate(maxSize) as we can use `collect` now
@adam-fowler adam-fowler merged commit 5c1f2ea into 2.x.x Feb 5, 2024
4 checks passed
@adam-fowler adam-fowler deleted the 2.x.x-requestbody branch February 5, 2024 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants