-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Add ISocketConnectionContextFactory #34769
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
Conversation
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs
Outdated
Show resolved
Hide resolved
This changes the memory pool and socketsender lifetime. We still want one of those per endpoint. |
Guessing that's why the shutdown tests are all failing :) Yeah the analogy I used during standup today is that I feel like I've transplanted a kidney into a lung cavity, still figuring out how stuff works, thanks for the early feedback. |
It wasn't clear to me how best to flow what is in the settings to the new SocketConnectionContextFactory when the API only had |
Looks like all the tests are passing now except for the unix domain sockets, not sure what's different about those There's a socket exception for the 2 unix socket tests: "An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call." (Looks like this is caused by accessing socket.NoDelay on unix sockets) |
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Kestrel/src/WebHostBuilderKestrelExtensions.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/IISocketConnectionContextFactory.cs
Outdated
Show resolved
Hide resolved
I'm assuming I should also update aspnetcore/src/Servers/Kestrel/Transport.Sockets/src/Client/SocketConnectionFactory.cs Line 74 in bdafb7a
|
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionOptions.cs
Outdated
Show resolved
Hide resolved
I don't think so. This abstraction is for use by third-party transports not for allowing people to create their own ConnectionContexts from Sockets. I don't think anyone asked for the latter, so I'd rather not support that if we don't have to. I don't think SocketTransportFactory should consume the (I)SocketConnectionContextFactory either. |
Okay I defer to you guys, just from the general purpose naming its a bit surprising that we wouldn't use it everywhere we create SocketConnectionContexts |
That's partly why I like removing the interface and not registering it with the IServiceCollection in UseKestrel(). In many cases, I expect it won't be registered as a service at all, but instead newed-up by a custom IConnectionListenerFactory with services it gets in its constructor. When I filed the API proposal, I was considering an interface and not the concrete class. So we'll need to add the constructor to the API proposal. I think the ILoggerFactory would be the only parameter though. |
Right now the transport factory is who new's up the SocketConnectionListener in Bind so if it doesn't use it, no-one will since the socket connection listener isn't currently getting created from DI no? |
Correct. This isn't for us to use. It's for third-party transports to use. So we'll definitely want to add some tests to make sure it all works end-to-end. |
What's so bad about just treating this as a normal service that is responsible for creating ConnectionContexts from a Socket and SocketConnectionOptions? I'm obviously coming at this from a totally naïve viewpoint...that's what the current naming would have me expect its responsibility is |
We have a lot more flexibility in the future we we don't consume the SocketConnectionContextFactory as a service in the socket transport. If we consume it as a service, that effectively forces us to change a public API any time we want to change the SocketConnection constructor. Sometimes this might be warranted anyway so third-party transports using it always have the same capabilities we do, but that might not always be necessary if we just continue calling the constructor directly with the internal pools we manage and whatnot. I like being able to make this decision on a case-by-case basis rather than be force into it. Anyone who's willing to do all the work to create a completely custom ConnectionContext from a Socket should just register their own IConnectionListenerFactory and bypass the socket transport completely since they've already done 90% of the work of implementing a custom IConnectionListenerFactory anyway. If someone just wants to decorate the ConnectionContext the socket transport would normally give you, they can use connection middleware and it'd work with any transport. |
I've updated the issue with my current thinking about how the API should look. I should have never made it an interface or called it a service. The reason we decided not to make it a static method as originally proposed is not so it can be replaced and injested by the socket transport, but so it can keep pools around between calls. |
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionOptions.cs
Outdated
Show resolved
Hide resolved
src/Servers/Kestrel/Transport.Sockets/src/PublicAPI.Shipped.txt
Outdated
Show resolved
Hide resolved
Pretty clean now, basically net changes look like we moved a bunch of code from the listener -> factory and split the transport options into two classes. Socket tests are green locally so I think this is ready for final review @halter73 @davidfowl |
/// <remarks> | ||
/// Defaults to <see cref="Environment.ProcessorCount" /> rounded down and clamped between 1 and 16. | ||
/// </remarks> | ||
public int IOQueueCount { get; set; } = Math.Min(Environment.ProcessorCount, 16); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It definitely affected the shipped public api's txt files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code check said no as well: Detected modification to baseline API files. PublicAPI.Shipped.txt files should only be updated after a major release. See /docs/APIBaselines.md for more information.
So back this out and just duplicate this in a new options class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think introducing a new base class by itself is a breaking change, but I'm pretty sure moving properties down to the new base class is. https://docs.microsoft.com/en-us/dotnet/core/compatibility/ says "Introducing a new base class" "REQUIRES JUDGMENT".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I reverted that and just added an internal copy constructor to flow things to the 'base' ContextFactory options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we could do this in a non breaking way by making the properties virtual and override them to call base or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you have is fine. Leave them separate.
src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionContextFactory.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is super clean.
OK @kevin-montrose we re-did the change and make a class that can be created (without DI) that has all of the implementation guts of the transport. To enable your scenario, you can write a custom transport that handles the listening logic on both the incoming server and the server being routed to. @mconnew for your scenario, we exposed the pipe settings so you can control the thresholds. We don't let you change the IDuplexPipe implementation before we read from the socket though. Hopefully that isn't a huge blocker. This should enable you to write a custom transport in CoreWCF without losing the behavior or performance enhancements we continue to make in the transport. |
Fixes #34522
Still trying to figure out why shutdown tests are failing, but want to see a full ci run