From b4c26f2d55acf689294e302f615e790eab35c1e9 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 25 May 2025 16:09:37 +0800 Subject: [PATCH] :bug: Fixes distributed lock --- .../Account/AccountEventService.cs | 18 ++++++++++++++++-- DysonNetwork.Sphere/Storage/CacheService.cs | 12 +++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/DysonNetwork.Sphere/Account/AccountEventService.cs b/DysonNetwork.Sphere/Account/AccountEventService.cs index 10d1eab..c8e7b2f 100644 --- a/DysonNetwork.Sphere/Account/AccountEventService.cs +++ b/DysonNetwork.Sphere/Account/AccountEventService.cs @@ -143,8 +143,21 @@ public class AccountEventService( { var lockKey = $"{CheckInLockKey}{user.Id}"; - await using var lk = await cache.AcquireLockAsync(lockKey, TimeSpan.FromMinutes(10), TimeSpan.Zero); - if (lk is null) throw new InvalidOperationException("Check-in was in progress."); + try + { + var lk = await cache.AcquireLockAsync(lockKey, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(100)); + + if (lk != null) + await lk.ReleaseAsync(); + } + catch + { + // Ignore errors from this pre-check + } + + // Now try to acquire the lock properly + await using var lockObj = await cache.AcquireLockAsync(lockKey, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(5)); + if (lockObj is null) throw new InvalidOperationException("Check-in was in progress."); var cultureInfo = new CultureInfo(user.Language, false); CultureInfo.CurrentCulture = cultureInfo; @@ -205,6 +218,7 @@ public class AccountEventService( s.SetProperty(b => b.Experience, b => b.Experience + result.RewardExperience) ); db.AccountCheckInResults.Add(result); + await db.SaveChangesAsync(); // Don't forget to save changes to the database await act.CreateActivity( user, diff --git a/DysonNetwork.Sphere/Storage/CacheService.cs b/DysonNetwork.Sphere/Storage/CacheService.cs index c03de04..3b9308f 100644 --- a/DysonNetwork.Sphere/Storage/CacheService.cs +++ b/DysonNetwork.Sphere/Storage/CacheService.cs @@ -117,8 +117,6 @@ public class RedisDistributedLock : IDistributedLock private readonly IDatabase _database; private bool _disposed; - private const string LockKeyPrefix = "Lock_"; - public string Resource { get; } public string LockId { get; } @@ -144,7 +142,7 @@ public class RedisDistributedLock : IDistributedLock var result = await _database.ScriptEvaluateAsync( script, - [$"{LockKeyPrefix}{Resource}"], + [$"{CacheServiceRedis.LockKeyPrefix}{Resource}"], [LockId, (long)timeSpan.TotalMilliseconds] ); @@ -166,7 +164,7 @@ public class RedisDistributedLock : IDistributedLock await _database.ScriptEvaluateAsync( script, - [$"{LockKeyPrefix}{Resource}"], + [$"{CacheServiceRedis.LockKeyPrefix}{Resource}"], [LockId] ); @@ -186,11 +184,11 @@ public class CacheServiceRedis : ICacheService private readonly JsonSerializerSettings _serializerSettings; // Global prefix for all cache keys - private const string GlobalKeyPrefix = "dyson:"; + public const string GlobalKeyPrefix = "dyson:"; // Using prefixes for different types of keys - private const string GroupKeyPrefix = GlobalKeyPrefix + "cg:"; - private const string LockKeyPrefix = GlobalKeyPrefix + "lock:"; + public const string GroupKeyPrefix = GlobalKeyPrefix + "cg:"; + public const string LockKeyPrefix = GlobalKeyPrefix + "lock:"; public CacheServiceRedis(IConnectionMultiplexer redis) {