Skip to content

Make all serve parameters consuming#11

Merged
gjcairo merged 8 commits intomainfrom
response-manager-serve
Sep 7, 2025
Merged

Make all serve parameters consuming#11
gjcairo merged 8 commits intomainfrom
response-manager-serve

Conversation

@gjcairo
Copy link
Collaborator

@gjcairo gjcairo commented Aug 19, 2025

This PR adds the necessary annotations to make all reader and writer types ~Copyable so that we can enforce call-once behaviour on the reader and writers.

It also exposes some additional state from the reader and writer to the server so that we can fail accordingly.

@gjcairo gjcairo requested a review from FranzBusch August 19, 2025 16:27

Choose a reason for hiding this comment

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

Are you planning to enable NonisolatedNonsendingByDefault on the whole target, which would make these unnecessary?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is already enabled and on closures this is still necessary AFAIK.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why SendableMetatype?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, this is because the closure in RequestResponseContext/withContext was marked as @Sendable and its signature is generic on arguments conforming to ConcludingAsyncReader and ConcludingAsyncWriter. But I actually don't think it should be @Sendable so I've removed this.

Comment on lines +65 to +68
final class ReaderState {
var trailers: HTTPFields? = nil
var finishedReading: Bool = false
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Some idea for us in the future. To avoid this allocation we could use an InlineArray<1, State> potentially that we share into the Reader and Writer. It would require the reader and writer to become ~Escapable but this might make it possible for us to avoid the allocation altogether.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is already enabled and on closures this is still necessary AFAIK.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's not really a context right? This is essentially the parameters to the request handler right? Do we really need this type and if we do can we come up with about better name + docs + separate file for it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah no, it's a very bad name but I didn't know what to call it :)

Sadly I think this type has to exist because tuples can't contain ~Copyable elements, and I need to be able to somehow spell the Input type of the middleware.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've renamed this to RequestResponseMiddlewareBox. I still hate it but open to suggestions.

I do have a question about its current shape though. I need to provide a withContents method so that users can access the stored request/reader/response sender. I could get around this by making the properties public instead, but then I'd have to mark the type as @frozen because, as the properties are consuming, you can't otherwise consume individual properties.

It annoys me a bit that we need a withContents method; but I'm not sure marking the type as frozen is good for API evolution either. So I decided to go with the former but I'd like to hear thoughts here too.

@gjcairo gjcairo requested a review from FranzBusch August 27, 2025 13:45
@gjcairo gjcairo force-pushed the response-manager-serve branch from d13e461 to e6d9933 Compare August 28, 2025 13:56
/// This type holds the values passed to the ``HTTPServerRequestHandler`` when handling a request.
/// It is necessary to box them together so that they can be used with `Middlewares`, as this will be the `Middleware.Input`.
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
public struct RequestResponseMiddlewareBox<
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not super happy with that name yet but don't wanna block the PR on naming bike-shedding. In particular, the HTTPServer target should know nothing about middleware. So maybe this is just a HTTPRequestHandlerInput or something along those lines? We should also explore using @frozen instead of the withContents method but can do that in a follow up PR. Since we are not ABI stable in this package we might be able to use it.

@gjcairo gjcairo merged commit a714c49 into main Sep 7, 2025
3 of 18 checks passed
@gjcairo gjcairo deleted the response-manager-serve branch September 7, 2025 19:02
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.

3 participants

Comments