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

Responsiveness under Working Conditions #242

Merged
merged 11 commits into from
Jan 21, 2025
Merged

Conversation

ehaydenr
Copy link
Contributor

Implementation of https://datatracker.ietf.org/doc/draft-ietf-ippm-responsiveness/ (draft 5) with flexible download and upload handlers to suit other use cases as well.

Motivation:

The provided handlers are useful for measuring responsiveness and testing things like performance of proxies

Modifications:

Add NIOHTTPResponsiveness and NIOHTTPResponsivenessServer

Result:

We'll now have an implementation of the Responsiveness under Working Conditions draft

Implementation of https://datatracker.ietf.org/doc/draft-ietf-ippm-responsiveness/ (draft 5) with
flexible download and upload handlers to suit other use cases as well.
@Lukasa Lukasa added the 🆕 semver/minor Adds new public API. label Dec 19, 2024
import NIOCore
import NIOHTTPTypes

/// HTTP request handler sending a configurable stream of zeroes
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we document that this requires the use of the HTTPTypes types, not the regular NIO ones.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can I suggest that, for now, we don't make the two "helper" handlers public? It's generally wise for us not to commit to too much API without a clear use-case. Making something public that was previously internal is generally easy, changing something that we accidentally made public is much harder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The two "helper" handlers you're referring to are the HTTPDrippingDownloadHandler and the HTTPReceiveDiscardHandler, right? The idea being only the ResponsivenessConfig and SimpleResponsivenessRequestMux end up being public?

I think doing that would end up making this more of an example than a building block. I find that request multiplexers are typically not very reusable (hence the prefix "Simple"). My expectation is that someone wanting to put together a robust implementation would have their own request mux and add things like limits on download size, delay durations, etc.

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 fair enough.

//
//===----------------------------------------------------------------------===//

public struct ResponsivenessConfig: Encodable {
Copy link
Contributor

@Lukasa Lukasa Dec 19, 2024

Choose a reason for hiding this comment

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

We should add the extra protocols to all of these. Codable, Hashable, Sendable.

@ehaydenr ehaydenr requested a review from Lukasa December 19, 2024 14:52
self.phase = .dripping(drippingState)
let this = NIOLoopBound(self, eventLoop: context.eventLoop)
let loopBoundContext = NIOLoopBound(context, eventLoop: context.eventLoop)
self.scheduled = context.eventLoop.scheduleTask(in: self.frequency) {
Copy link
Contributor

Choose a reason for hiding this comment

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

A recent-ish NIO got a scheduleCallback API which is slightly cheaper than scheduleTask: https://github.com/apple/swift-nio/blob/56f9b7c6fc9525ba36236dbb151344f8c35288df/Sources/NIOCore/EventLoop.swift#L378-L381

Might be worth using that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I think I used it mostly correctly, but I'm not 100% sure. I haven't built much intuition around when swift does or doesn't allocate. I did find the fact that scheduleCallback throws a bit surprising and looked for an equivalent syncOperations-like method to avoid the try, but I didn't find one. I think try! may be fine in practice given current implementations, but not entirely correct. Interested in your feedback here.

Comment on lines 233 to 234
// SAFTEY: scheduling the callback only potentially throws when invoked off eventloop
try! context.eventLoop.scheduleCallback(in: self.frequency, handler: self.scheduledCallbackHandler!)
Copy link
Contributor

Choose a reason for hiding this comment

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

Different EL implementations could throw for other reasons. In practice that probably won't be the case but it'd be safer to catch the error and call context.fireErrorCaught instead of try! here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point - fixed

@ehaydenr ehaydenr requested a review from glbrntt January 6, 2025 17:52
@glbrntt
Copy link
Contributor

glbrntt commented Jan 7, 2025

@Lukasa did you also want to review as you left a few comments before?

Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

I think this looks great, let's land it.

@Lukasa
Copy link
Contributor

Lukasa commented Jan 20, 2025

Apologies for the delay here @ehaydenr, mind fixing up the conflicts for me?

@Lukasa Lukasa enabled auto-merge (squash) January 21, 2025 17:11
@Lukasa Lukasa merged commit 4804de1 into apple:main Jan 21, 2025
22 checks passed
@ehaydenr ehaydenr deleted the ippmresponsiveness branch January 21, 2025 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🆕 semver/minor Adds new public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants