public virtual void Clear() { log.DebugFormat("clear cache: regionName='{0}'", RegionName); try { var setOfActiveKeysKey = CacheNamespace.GetSetOfActiveKeysKey(); var db = GetDatabase(); db.KeyDelete(setOfActiveKeysKey, fireAndForgetFlags); } catch (Exception e) { log.ErrorFormat("could not clear cache: regionName='{0}'", RegionName); var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Clear, e); options.OnException(this, evtArg); if (evtArg.Throw) { throw new RedisCacheException(RegionName, "Failed to clear cache. See inner exception.", e); } } }
public async Task ClearCoreAsync(CancellationToken cancellationToken, bool sync = false) { cancellationToken.ThrowIfNull("cancellationToken"); if (cancellationToken.IsCancellationRequested) { return; } log.Debug("clear cache: regionName='{0}'", RegionName); try { var setOfActiveKeysKey = CacheNamespace.GetSetOfActiveKeysKey(); var db = GetDatabase(); if (sync) { db.KeyDelete(setOfActiveKeysKey, fireAndForgetFlags); } else { await db.KeyDeleteAsync(setOfActiveKeysKey, fireAndForgetFlags); } } catch (Exception e) { log.Error("could not clear cache: regionName='{0}'", RegionName); var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Clear, e); options.OnException(this, evtArg); if (evtArg.Throw) { throw new RedisCacheException(RegionName, "Failed to clear cache. See inner exception.", e); } } }
private async Task UnlockCoreAsync(object key, CancellationToken cancellationToken, bool sync = false) { cancellationToken.ThrowIfNull("cancellationToken"); if (cancellationToken.IsCancellationRequested) { return; } // Use Remove() instead of Get() because we are releasing the lock // anyways. var lockData = acquiredLocks.Remove(Convert.ToString(key)) as LockData; if (lockData == null) { log.Warn("attempted to unlock '{0}' but a previous lock was not acquired or timed out", key); var unlockFailedEventArgs = new UnlockFailedEventArgs( RegionName, key, lockKey: null, lockValue: null ); options.OnUnlockFailed(this, unlockFailedEventArgs); return; } log.Debug("releasing cache lock: regionName='{0}', key='{1}', lockKey='{2}', lockValue='{3}'", RegionName, lockData.Key, lockData.LockKey, lockData.LockValue ); try { var db = GetDatabase(); var args = new { lockKey = lockData.LockKey, lockValue = lockData.LockValue }; // Don't use IDatabase.LockRelease() because it uses watch/unwatch // where we prefer an atomic operation (via a script). var wasLockReleased = sync ? (bool)db.ScriptEvaluate(unlockScript, args) : (bool)await db.ScriptEvaluateAsync(unlockScript, args); if (!wasLockReleased) { log.Warn("attempted to unlock '{0}' but it could not be released (it maybe timed out or was cleared in Redis)", lockData); var unlockFailedEventArgs = new UnlockFailedEventArgs( RegionName, key, lockData.LockKey, lockData.LockValue ); options.OnUnlockFailed(this, unlockFailedEventArgs); } } catch (Exception e) { log.Error("could not release cache lock: regionName='{0}', key='{1}', lockKey='{2}', lockValue='{3}'", RegionName, lockData.Key, lockData.LockKey, lockData.LockValue ); var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Unlock, e); options.OnException(this, evtArg); if (evtArg.Throw) { throw new RedisCacheException(RegionName, "Failed to unlock item in cache. See inner exception.", e); } } }
private async Task LockCoreAsync(object key, CancellationToken cancellationToken, bool sync = false) { cancellationToken.ThrowIfNull("cancellationToken"); if (cancellationToken.IsCancellationRequested) { return; } log.Debug("acquiring cache lock: regionName='{0}', key='{1}'", RegionName, key); try { var lockKey = CacheNamespace.GetLockKey(key); var shouldRetry = options.AcquireLockRetryStrategy.GetShouldRetry(); var wasLockAcquired = false; var shouldTryAcquireLock = true; while (shouldTryAcquireLock) { var lockData = new LockData( key: Convert.ToString(key), lockKey: lockKey, // Recalculated each attempt to ensure a unique value. lockValue: options.LockValueFactory.GetLockValue() ); bool lockAquired = sync ? this.TryAcquireLockAsync(lockData, true).ConfigureAwait(false).GetAwaiter().GetResult() : await this.TryAcquireLockAsync(lockData); if (lockAquired) { wasLockAcquired = true; shouldTryAcquireLock = false; } else { var shouldRetryArgs = new ShouldRetryAcquireLockArgs( RegionName, lockData.Key, lockData.LockKey, lockData.LockValue, lockTimeout, acquireLockTimeout ); shouldTryAcquireLock = shouldRetry(shouldRetryArgs); } } if (!wasLockAcquired) { var lockFailedArgs = new LockFailedEventArgs( RegionName, key, lockKey, lockTimeout, acquireLockTimeout ); options.OnLockFailed(this, lockFailedArgs); } } catch (Exception e) { log.Error("could not acquire cache lock: regionName='{0}', key='{1}'", RegionName, key); var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Lock, e); options.OnException(this, evtArg); if (evtArg.Throw) { throw new RedisCacheException(RegionName, "Failed to lock item in cache. See inner exception.", e); } } }
private async Task <object> GetCoreAsync(object key, CancellationToken cancellationToken, bool sync = false) { key.ThrowIfNull(); cancellationToken.ThrowIfNull("cancellationToken"); if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <object>(cancellationToken)); } log.Debug("get from cache: regionName='{0}', key='{1}'", RegionName, key); try { var cacheKey = CacheNamespace.GetKey(key); var setOfActiveKeysKey = CacheNamespace.GetSetOfActiveKeysKey(); var db = GetDatabase(); var args = new { key = cacheKey, setOfActiveKeysKey = setOfActiveKeysKey }; var resultValues = sync ?(RedisValue[])db.ScriptEvaluate(getScript, args) :(RedisValue[])await db.ScriptEvaluateAsync(getScript, args); if (resultValues[0].IsNullOrEmpty) { log.Debug("cache miss: regionName='{0}', key='{1}'", RegionName, key); return(null); } else { var serializedResult = resultValues[0]; var deserializedValue = options.Serializer.Deserialize(serializedResult); if (deserializedValue != null && slidingExpiration != RedisCacheConfiguration.NoSlidingExpiration) { var slidingArgs = new { key = cacheKey, expiration = expiration.TotalMilliseconds, slidingExpiration = slidingExpiration.TotalMilliseconds }; if (sync) { db.ScriptEvaluate(slidingExpirationScript, slidingArgs, fireAndForgetFlags); } else { await db.ScriptEvaluateAsync(slidingExpirationScript, slidingArgs, fireAndForgetFlags); } } return(deserializedValue); } } catch (Exception e) { log.Error("could not get from cache: regionName='{0}', key='{1}'", RegionName, key); var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Get, e); options.OnException(this, evtArg); if (evtArg.Throw) { throw new RedisCacheException(RegionName, "Failed to get item from cache. See inner exception.", e); } return(null); } }