-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Remove IsAvailable check on CommitAsync. #43059
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
Remove IsAvailable check on CommitAsync. #43059
Conversation
@@ -262,12 +262,6 @@ public async Task LoadAsync(CancellationToken cancellationToken = default) | |||
/// <inheritdoc /> | |||
public async Task CommitAsync(CancellationToken cancellationToken = default) | |||
{ | |||
if (!IsAvailable) |
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.
// use field to avoid loading the session via IsAvailable property
if (!_isAvailable)
?
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.
Not sure we want that; if _isAvailable
wasn't set, it could be that we never attempted to load it. The current code attempts to load in that case.
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.
Why would we remove this check in CommitAsync
but not in Set
?
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.
Set
always depends on IsAvailable
, but CommitAsync
might not need to load the session if _isModified
isn't true. The IsAvailable
check was added in CommitAsync
during the nullability work but I don't see why it's necessary now.
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 see. And it could force sync-over-async as well. Yuck!
@adityamandaleeka Will this regression fix be back ported to .NET 6 (LTS) ? |
Hi @csturm83. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@csturm83 It doesn't seem severe enough for a 6.0 backport, but we could consider it if there's a compelling use case that's broken. |
@adityamandaleeka Between the unexpected/undocumented behavior change (exiting early vs. throwing an exception), consistency/symmetry with LoadAsync exceptional behavior, performance hit of potential extra deserialization, synch over async, etc. - in my opinion, it seems worth it. That, and it's a relatively focused change that restores documented behavior and expectations (addresses a regression). |
Hi @csturm83. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@csturm83 backporting is expensive and risky, a bug must have high impact and no viable workaround. While in-efficient, it's not clear that this bug is causing a blocking issue for you? |
Just wanted to let you guys know that the IsAvailable call you're discussing was causing massive CPU load on our servers. Scenario: We originally used MongoDB for our IDistributedCache implementation, and that worked well for a while when our traffic was low. As our server load grew we started moving our code to Redis with the expectation of reducing overhead. Imagine our surprise when Redis actually consumed an order of magnitude more CPU on the web servers than the previous MongoDB implementation. We used the StackExchange Redis driver with Microsoft.Extensions.Caching.StackExchangeRedis for the ASP.NET Core integration, really standard stuff. To make a long story short, after much analysis it turns out that having IsAvailable in CommitAsync (DistributedSession class) forces the Redis driver to do a sync get on every page load, and apparently StackExchange Redis is not that efficient with sync calls. Solutions tried:
Only the last option worked well enough to actually decrease load on the web servers to approximately what we saw with the older MongoDB implementation. To me, it seems like this issue can cause a massive performance drop under pretty common circumstances. Especially given that the official docs recommend the exact setup that we had (https://learn.microsoft.com/en-us/aspnet/core/performance/caching/distributed) |
Hi @Alex-Covecube. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@Tratcher see @Alex-Covecube 's comment above (wasn't sure if comments on closed issues generate notification without an @ mention). Silent performance traps that can spike CPU usage could be costly. For those of us in enterprise tied to LTS releases, it would be a shame to have to wait until 8.0 for this regression fix. |
Hi @csturm83. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@Alex-Covecube thanks for letting us know. I've reopened the issue for backport consideration. |
Fix #42009
I did some archaeology into how we ended up adding this check. I think (but am not certain yet) this was added because one of the incremental states of #26098 had a null-forgiving operator on the
IdBytes
getter.IdBytes
could return null ifIsAvailable
wasn't set.This led to the addition of the
if (!IsAvailable)
check inSerialize
which was subsequently moved toCommitAsync
based on this comment.However, the
IdBytes
getter was changed to make its result non-null:aspnetcore/src/Middleware/Session/src/DistributedSession.cs
Lines 119 to 131 in bf02bf2
Assuming this was the concern that led to the
IsAvailable
check being added toCommitAsync
, I think we're okay to remove it. I'd like another pair of eyes on this though.