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
SignalR performance: track groups per connection, remove on disconnect #53486
Conversation
…net#48249 Instead of iterating over ALL the groups, which is slow and even introduces a DDoS vector, we remove from groups that are specific to this connection
Does it need to be a feature? Can we just add a list of groups to the connection context? We can optimize with our own internal state. |
Can we also delete RemoveFromDisconnection since it's no longer used? |
In case you're asking me:
Performance-wise doesn't matter they're both just dictionaries under the hood.
What is |
It's less dictionaries. Seems apt for our default implementation to be as optimized as it could be.
It's an internal type. |
Sure, I'll remove the unused method ASAP, and rewrite it into P.S. I forgot to mention that this change also drastically speeds up application shutdown. When you "recycle" application pool on IIS/Windows, or you gracefully end Kestrel process on Linux, or you just switch nginx-proxy to a new application instance in a blue-green scenario (also on Linux) - you literally get thousands and thousands of "disconnect" events. And shutting down a SignalR app process results in CPU load jumping to 100% and stay there for 10-40 seconds (depending on the number of connections and how beefed up the server is). That is why I'm humbly suggesting releasing this change as a 8.0.x patch |
Co-authored-by: Brennan <brecon@microsoft.com>
I think he meant making the |
@BrennanConroy oh, got it. Sure, just updated the PR! |
@BrennanConroy is this good to go? Do we need any other tests? |
Thanks @alex-jitbit! I know the review comments were a bit spread out so thanks for sticking with it. As for backporting the changes I think that's not too bad since the only way to workaround it would be to do some private reflection. |
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/aspnetcore/actions/runs/7809566574 |
Instead of iterating over ALL the connection-groups, which is slow and even introduces a DDoS vector, we remove from groups that are specific to this connection upon disconnect.
Signalr CPU optimization
Similar to
RedisHubLifetimeManager
the newDefaultHubLifetimeManager
now makes every connection track groups per connection. So when a client disconnects there's no need to iterate a huge dictionary of all groups (there can be tens of thousands.This change should also drastically speed up application shutdown. When you "recycle" application pool on IIS/Windows, or you gracefully end Kestrel process on Linux, or switch nginx-proxy between application instances in a blue-green scenario - you literally get thousands and thousands of "disconnected" events)
Fixes #48249