-
-
Notifications
You must be signed in to change notification settings - Fork 36
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
GetOrSetAsync fails to write value to redis when any redis extensions are enabled #104
Comments
Looking at the lock extension, seems the issue might be here. I think you're using the same cache key for the lock as the value, so it removes the value when it removes the lock. Still looking at why the remote eviction might also cause an issue. var hasLock = await Database.StringSetAsync(cacheKey, RedisValue.EmptyString, expiry: LockTimeout, when: When.NotExists);
if (hasLock)
{
try
{
var cacheEntry = await valueProvider();
await Subscriber.PublishAsync(RedisChannel, cacheKey, CommandFlags.FireAndForget);
return cacheEntry;
}
finally
{
await Database.KeyDeleteAsync(cacheKey, CommandFlags.FireAndForget);
} |
I think I confirmed the lock issue. If I set the lock extension to use a different redis database, then it works. |
I think I've got the eviction issue narrowed down, though not totally sure. Either way, the Subscribe method doesn't take an async handler, it's a sync Action. StackExchange/StackExchange.Redis#639 There's an OnMessage version of the subscriber that does take an async handler however, and could be used in place. https://stackexchange.github.io/StackExchange.Redis/Basics#using-redis-pubsub |
Figured it out. It's not the async handler, though maybe that should be fixed also? The issue is the remote eviction itself. I actually had another instance of my app running on azure, and so it was subscribed as well. The remove eviction on the azure instance calls EvictAsync on the ICacheStack which evicts all the layers, including redis! I think the intention is that remote eviction should only evict the local caches. |
Great work chasing up all of this - saves a lot of time debugging the issues!
Hmmm, I wonder if that may have been one of the causes of issues in my tests.
Yeah, that should definitely be fixed. I find it strange that there is no compiler error or anything for how I currently have it set up.
Wow - that is really bad, can't believe I missed that when writing it. Definitely need more tests around that scenario.
Yeah. When calling Gonna need to work out how I can best co-ordinate that logic. Likely it will be changing the following to not ask the cache stack to evict it directly - maybe will need an CacheTower/src/CacheTower.Extensions.Redis/RedisRemoteEvictionExtension.cs Lines 64 to 67 in a3f9c98
|
(Still me) |
I think that issue with the lock extension still exists. The lock uses the same cache key as the value, so deleting the lock deletes the value, or on subsequent tries where the value might exist, would always fail to get a lock. |
Perhaps also take a look at incorporating redlock.net into this extension for the lock taking. |
Thanks for reminding me about the locking issue! The fix is simple enough, allow an option to configure a lock key format - this is the same logic that Redlock.NET does. Regarding using Redlock.NET entirely, it seems a little heavy for what it does and with the changes I've done, locking should work correctly now. If I do have more issues with locking etc in the future, I may reconsider it though. |
Noticed the fixes have all been merged, awesome! Are you planning a nuget release this week? |
Should be - just checking a few final things, want to make sure CI builds are stable. |
I've released 0.7.0 with the Redis fixes. Thanks again for raising the issues, if you encounter any others, let me know! |
I'm trying a basic redis backed setup. SetAsync works, but GetOrSetAsync is not setting the value into redis. It is setting the value into memory however, and does return the expected value.
If I remove the redis extensions, then it works and does set the value into redis. However I can't really use redis without them, since I have scaled app services in azure. Note I need to remove both redis extensions, having either one will cause the problem.
Here's a basic reproducer I mocked up in linqpad.
The text was updated successfully, but these errors were encountered: