This looks good. I don’t think Hummingbird will have any issues moving to using the AsyncSequence based HTTP body.
The only issue I can see is I am still going to need to copy all the body data as I am converting between NIO ByteBuffer and ArraySlice unless someone on the NIO team has a clever way to avoid this.
i was not aware of anyone moving towards a standard bytebuffer type because i wasn't aware that any such type existed besides NIOCore.ByteBuffer. is there a library besides SwiftNIO that people are moving towards now to replace ByteBuffer?
/// Describes how many times the provided sequence can be iterated.
public enum IterationBehavior : Sendable {
/// The input sequence can only be iterated once.
///
/// If a retry or a redirect is encountered, fail the call with
/// a descriptive error.
case single
/// The input sequence can be iterated multiple times.
///
/// Supports retries and redirects, as a new iterator is created each
/// time.
case multiple
}
I just re-read the ownership modifiers proposal and thought these names may also be a good fit here i.e. consume instead of single and borrow for multiple.
The HTTPBody.init has a couple of overloads that take a Sequence/Collection of "Strings"/"Bytes", concretely these types:
some Sequence<some StringProtocol>
some Collection<some StringProtocol>
some Sequence<ArraySlice<UInt8>>
some Collection<ArraySlice<UInt8>>
They could all be replaced by importing AsyncAlgorithms and using the .async operator as that's how they are internally transformed. The only benefit I see is for the overload that take some Collection as a Collection can always be iterated multiple times. We would lose this information if we use the .async modifier and users would need to manually specify .multiple. I'm wondering if this warrants the number of overloads.
That's a great idea, and I'd happily adopt those names. Before I do, are we sure that using the same names will be a positive for consistency? Or could it actually be more confusing because the methods taking this parameter will not actually have the language-level keywords?
Trying to think about another example of using the same words as keywords, would we prefer or actually find confusing if there was a parameter accessModifier that took one of the values public, internal, private, but meant something application-specific?
But maybe I'm being too cautious, just wanted to double check before I go and update the proposal that we've considered this. WDYT?
extension HTTPBody {
/// Creates a new body with the provided async sequence of byte sequences.
/// - Parameters:
/// - sequence: An async sequence that provides the byte chunks.
/// - length: The total lenght of the body.
/// - iterationBehavior: The iteration behavior of the sequence, which
/// indicates whether it can be iterated multiple times.
@inlinable public convenience init<S, ES>(
_ sequence: S,
length: HTTPBody.Length,
iterationBehavior: IterationBehavior
) where S: Sendable, S: AsyncSequence, ES: Sequence, ES == S.Element, ES.Element == UInt8
}
Might just be me, but I found the additional type parameter in the signature confusing, rather than using S.Element in the type constraints, e.g.
I would also appreciate describing names for the generic parameters instead of single letters, e.g. Bytes.
In addition, I would prefer the use of opaque parameters where possible.
The review period for this proposal is now over, and all suggested changes have been implemented.
For a complete picture of the discussed topics, you can refer to the previous comments on this thread, as well as the conversation on the PR.
The proposal is accepted. SOAR-0004 is now Ready for Implementation.