-
-
Notifications
You must be signed in to change notification settings - Fork 101
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
ImageSharp.Web.Caching.AsyncKeyLock.GetDoorman: System.InvalidOperationException #63
Comments
Hey @dotli Thanks for filling out the template. Can you please provide steps to reproduce the issue. The stacktrace is useful but I don't know how to reproduce the problem. |
Since you both helped write the locking code I thought it was best to get a deeper understanding here. We're using I'm also able to cause the internal Dictionary to throw private async Task AsyncLockCanLockByKey()
{
bool zeroEntered = false;
bool entered = false;
int index = 0;
Task[] tasks = Enumerable.Range(0, 5).Select(i => Task.Run(async () =>
{
using (await AsyncLock.WriterLockAsync(AsyncKey).ConfigureAwait(false))
{
if (i == 0)
{
entered = true;
zeroEntered = true;
await Task.Delay(3000).ConfigureAwait(false);
entered = false;
}
else if (zeroEntered)
{
Assert.False(entered);
}
index++;
}
})).ToArray();
await Task.WhenAll(tasks);
Assert.Equal(5, index);
} Any ideas? References |
See also. #64 I managed to replicate this at one point but not sure how as I was hacking together the above test. |
SpinLock is a mutable struct. Calling methods on a |
Agh, I've been burned by this exact problem enough times now that you'd think I would have learned by now. @omariom and @Drawaes are correct. Dropping the That said, I think this AsyncKeyLock system could potentially be improved a bit. As currently implemented it has the potential to become a bottleneck under heavy concurrent access. And while that may not be a huge problem for ImageSharp.Web given the realistic throughput of a server running something as heavy-weight as image processing, I've seen this same exact AsyncKeyLock code being copied into other codebases where really high concurrency is a potential concern, so it's probably worth making this as solid as possible. A few months ago I overhauled the locking logic in our own codebase and was able to replace the SpinLock+Dictionary logic with a proper ConcurrentDictionary. It might be worth trying to port that into ImageSharp.Web. I'm currently in Costa Rica on vacation with my family (yeah I know, I really shouldn't be replying to GitHub issues right now...), but when I get back I'll see if I can find some time to port it over and open up a PR to discuss the merits of it. |
Thanks for the input guys, all very helpful! ❤️ @kroymann Tut, tut. get back to your holiday! We'll chat when you're back, keen to hear your ideas. |
Description
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
Steps to Reproduce
System Configuration
SixLabors.ImageSharp 1.0.0-dev002697
Windows Server 2012 Standard
.Net Core 2.1
The text was updated successfully, but these errors were encountered: