Пример #1
0
        public virtual object Get(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("get from cache : {0}", key);

            try
            {
                Task <RedisValue> getCacheValue = null;

                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey  = CacheNamespace.GetKey(key);
                    getCacheValue = transaction.StringGetAsync(cacheKey);
                });

                var data = connectionMultiplexer.Wait(getCacheValue);
                return(Deserialize(data));
            }
            catch (Exception e)
            {
                log.ErrorFormat("coult not get from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }

                return(null);
            }
        }
Пример #2
0
        public virtual void Remove(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("remove from cache : {0}", key);

            try
            {
                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey = CacheNamespace.GetKey(key);
                    transaction.KeyDeleteAsync(cacheKey, CommandFlags.FireAndForget);
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not remove from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        public virtual void Remove(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("remove from cache : {0}", key);

            try
            {
                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        ((RedisNativeClient)r).Del(cacheKey);
                    });
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not remove from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
Пример #4
0
        public virtual void Put(object key, object value)
        {
            key.ThrowIfNull("key");
            value.ThrowIfNull("value");

            log.DebugFormat("put in cache : {0}", key);

            try
            {
                var data = Serialize(value);

                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey = CacheNamespace.GetKey(key);
                    transaction.StringSetAsync(cacheKey, data, expiry, flags: CommandFlags.FireAndForget);

                    var setOfKeysKey = CacheNamespace.GetSetOfKeysKey();
                    transaction.SetAddAsync(setOfKeysKey, cacheKey, flags: CommandFlags.FireAndForget);
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not put in cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        public virtual object Get(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("get from cache : {0}", key);

            try
            {
                byte[] data = null;

                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        return(((IRedisNativeClient)r).Get(cacheKey));
                    }, x => data = x);
                });

                return(serializer.Deserialize(data));
            }
            catch (Exception e)
            {
                log.ErrorFormat("coult not get from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }

                return(null);
            }
        }
        public virtual void Unlock(object key)
        {
            string globalKey;

            if (!acquiredLocks.TryGetValue(key, out globalKey))
            {
                return;
            }

            log.DebugFormat("releasing cache lock : {0}", key);

            try
            {
                using (var client = this.clientManager.GetClient())
                {
                    client.Remove(globalKey);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not release cache lock : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
Пример #7
0
        public virtual void Clear()
        {
            var generationKey = CacheNamespace.GetGenerationKey();
            var setOfKeysKey  = CacheNamespace.GetSetOfKeysKey();

            log.DebugFormat("clear cache : {0}", generationKey);

            try
            {
                var db          = GetDatabase();
                var transaction = db.CreateTransaction();

                var incrementGeneration = transaction.StringIncrementAsync(generationKey);

                transaction.KeyDeleteAsync(setOfKeysKey, CommandFlags.FireAndForget);

                transaction.Execute();

                var newGeneration = transaction.Wait(incrementGeneration);
                CacheNamespace.SetHigherGeneration(newGeneration);
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not clear cache : {0}", generationKey);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        protected virtual void OnException(RedisCacheExceptionEventArgs e)
        {
            var isSocketException = e.Exception is SocketException || e.Exception.InnerException is SocketException;

            if (!isSocketException)
            {
                e.Throw = true;
            }
        }
Пример #9
0
        protected void SyncGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    CacheNamespace.SetGeneration(FetchGeneration());
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }
Пример #10
0
        public virtual void Lock(object key)
        {
            log.DebugFormat("acquiring cache lock : {0}", key);

            try
            {
                var lockKey = CacheNamespace.GetLockKey(key);

                Retry.UntilTrue(() =>
                {
                    var lockData = new LockData(
                        key: Convert.ToString(key),
                        lockKey: lockKey,
                        lockValue: GetLockValue()
                        );

                    var db           = GetDatabase();
                    var wasLockTaken = db.LockTake(lockData.LockKey, lockData.LockValue, lockTimeout);

                    if (wasLockTaken)
                    {
                        // It's ok to use Set() instead of Add() because the
                        // lock in Redis will cause other clients to wait.
                        acquiredLocks.Set(lockData.Key, lockData, absoluteExpiration: DateTime.UtcNow.Add(lockTimeout));
                    }

                    return(wasLockTaken);
                }, lockTimeout);
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not acquire cache lock : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        protected void SyncGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    CacheNamespace.SetGeneration(FetchGeneration());
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
Пример #12
0
        private void SyncInitialGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    var latestGeneration = FetchGeneration();
                    CacheNamespace.SetHigherGeneration(latestGeneration);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync initial generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        public virtual void Put(object key, object value)
        {
            key.ThrowIfNull("key");
            value.ThrowIfNull("value");

            log.DebugFormat("put in cache : {0}", key);

            try
            {
                var data = serializer.Serialize(value);

                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        ((IRedisNativeClient)r).SetEx(cacheKey, expirySeconds, data);
                    });

                    transaction.QueueCommand(r =>
                    {
                        var globalKeysKey = CacheNamespace.GetGlobalKeysKey();
                        var cacheKey      = CacheNamespace.GlobalCacheKey(key);
                        r.AddItemToSet(globalKeysKey, cacheKey);
                    });
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not put in cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
Пример #14
0
        public virtual void Unlock(object key)
        {
            // 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.WarnFormat("attempted to unlock '{0}' but a previous lock was not acquired or timed out", key);
                return;
            }

            log.DebugFormat("releasing cache lock : {0}", lockData);

            try
            {
                var db = GetDatabase();

                var wasLockReleased = db.LockRelease(lockData.LockKey, lockData.LockValue);

                if (!wasLockReleased)
                {
                    log.WarnFormat("attempted to unlock '{0}' but it could not be relased (maybe timed out or was cleared in Redis)", lockData);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not release cache lock : {0}", lockData);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        public virtual void Clear()
        {
            var generationKey = CacheNamespace.GetGenerationKey();
            var globalKeysKey = CacheNamespace.GetGlobalKeysKey();

            log.DebugFormat("clear cache : {0}", generationKey);

            try
            {
                using (var client = this.clientManager.GetClient())
                    using (var transaction = client.CreateTransaction())
                    {
                        // Update to a new generation.
                        transaction.QueueCommand(r =>
                                                 r.Increment(generationKey, 1),
                                                 x => CacheNamespace.SetGeneration(x));

                        // Empty the set of current keys for this region.
                        // NOTE: The actual cached objects will eventually expire.
                        transaction.QueueCommand(
                            r => r.Remove(globalKeysKey));

                        transaction.Commit();
                    }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not clear cache : {0}", generationKey);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
        public virtual void Lock(object key)
        {
            log.DebugFormat("acquiring cache lock : {0}", key);

            try
            {
                var globalKey = CacheNamespace.GlobalKey(key, RedisNamespace.NumTagsForLockKey);

                using (var client = this.clientManager.GetClient())
                {
                    // Derived from ServiceStack's RedisLock.
                    ExecExtensions.RetryUntilTrue(() =>
                    {
                        var wasSet = true; //client.SetEntryIfNotExists(globalKey, "lock " + DateTime.UtcNow.ToUnixTime());

                        if (wasSet)
                        {
                            acquiredLocks[key] = globalKey;
                        }

                        return(wasSet);
                    }, lockTimeout);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not acquire cache lock : ", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
Пример #17
0
        public virtual object Get(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("get from cache : {0}", key);

            try
            {
                Task<RedisValue> getCacheValue = null;

                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey = CacheNamespace.GetKey(key);
                    getCacheValue = transaction.StringGetAsync(cacheKey);
                });

                var data = connectionMultiplexer.Wait(getCacheValue);
                return Deserialize(data);
            }
            catch (Exception e)
            {
                log.ErrorFormat("coult not get from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;

                return null;
            }
        }
Пример #18
0
        public virtual void Put(object key, object value)
        {
            key.ThrowIfNull("key");
            value.ThrowIfNull("value");

            log.DebugFormat("put in cache : {0}", key);

            try
            {
                var data = Serialize(value);

                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey = CacheNamespace.GetKey(key);
                    transaction.StringSetAsync(cacheKey, data, expiry, flags: CommandFlags.FireAndForget);

                    var setOfKeysKey = CacheNamespace.GetSetOfKeysKey();
                    transaction.SetAddAsync(setOfKeysKey, cacheKey, flags: CommandFlags.FireAndForget);
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not put in cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
Пример #19
0
        public virtual void Remove(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("remove from cache : {0}", key);

            try
            {
                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        ((RedisNativeClient)r).Del(cacheKey);
                    });
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not remove from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }
Пример #20
0
        public virtual void Clear()
        {
            var generationKey = CacheNamespace.GetGenerationKey();
            var globalKeysKey = CacheNamespace.GetGlobalKeysKey();

            log.DebugFormat("clear cache : {0}", generationKey);

            try
            {
                using (var client = this.clientManager.GetClient())
                using (var transaction = client.CreateTransaction())
                {
                    // Update to a new generation.
                    transaction.QueueCommand(r =>
                        r.Increment(generationKey, 1),
                        x => CacheNamespace.SetGeneration(x));

                    // Empty the set of current keys for this region.
                    // NOTE: The actual cached objects will eventually expire.
                    transaction.QueueCommand(
                        r => r.Remove(globalKeysKey));

                    transaction.Commit();
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not clear cache : {0}", generationKey);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }
Пример #21
0
        public virtual void Lock(object key)
        {
            log.DebugFormat("acquiring cache lock : {0}", key);

            try
            {
                var globalKey = CacheNamespace.GlobalKey(key, RedisNamespace.NumTagsForLockKey);

                using (var client = this.clientManager.GetClient())
                {
                    // Derived from ServiceStack's RedisLock.
                    ExecExtensions.RetryUntilTrue(() => 
                    {
                        var wasSet = client.SetEntryIfNotExists(globalKey, "lock " + DateTime.UtcNow.ToUnixTime());

                        if (wasSet)
                        {
                            acquiredLocks[key] = globalKey;
                        }

                        return wasSet;
                    }, lockTimeout);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not acquire cache lock : ", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }
Пример #22
0
        protected virtual void OnException(RedisCacheExceptionEventArgs e)
        {
            var isSocketException = e.Exception is SocketException || e.Exception.InnerException is SocketException;

            if (!isSocketException)
            {
                e.Throw = true;
            }
        }
Пример #23
0
        public virtual void Unlock(object key)
        {
            string globalKey;
            if (!acquiredLocks.TryGetValue(key, out globalKey)) { return; }

            log.DebugFormat("releasing cache lock : {0}", key);

            try
            {
                using (var client = this.clientManager.GetClient())
                {
                    client.Remove(globalKey);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not release cache lock : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }
Пример #24
0
 private static void DefaultOnException(RedisCacheExceptionEventArgs e)
 {
     e.Throw = true;
 }
Пример #25
0
        public virtual object Get(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("get from cache : {0}", key);

            try
            {
                byte[] data = null;

                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        return ((IRedisNativeClient)r).Get(cacheKey);
                    }, x => data = x);
                });
                
                return serializer.Deserialize(data);

            }
            catch (Exception e)
            {
                log.ErrorFormat("coult not get from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }

                return null;
            }
        }
Пример #26
0
 private void OnException(RedisCacheExceptionEventArgs e)
 {
     options.OnException(e);
 }
Пример #27
0
        public virtual void Lock(object key)
        {
            log.DebugFormat("acquiring cache lock : {0}", key);

            try
            {
                var lockKey = CacheNamespace.GetLockKey(key);

                Retry.UntilTrue(() =>
                {
                    var lockData = new LockData(
                        key: Convert.ToString(key),
                        lockKey: lockKey,
                        lockValue: GetLockValue()
                    );

                    var db = GetDatabase();
                    var wasLockTaken = db.LockTake(lockData.LockKey, lockData.LockValue, lockTimeout);

                    if (wasLockTaken)
                    {
                        // It's ok to use Set() instead of Add() because the 
                        // lock in Redis will cause other clients to wait.
                        acquiredLocks.Set(lockData.Key, lockData, absoluteExpiration: DateTime.UtcNow.Add(lockTimeout));
                    }

                    return wasLockTaken;
                }, lockTimeout);
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not acquire cache lock : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
Пример #28
0
        public virtual void Remove(object key)
        {
            key.ThrowIfNull();

            log.DebugFormat("remove from cache : {0}", key);

            try
            {
                ExecuteEnsureGeneration(transaction =>
                {
                    var cacheKey = CacheNamespace.GetKey(key);
                    transaction.KeyDeleteAsync(cacheKey, CommandFlags.FireAndForget);
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not remove from cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
Пример #29
0
        public virtual void Clear()
        {
            var generationKey = CacheNamespace.GetGenerationKey();
            var setOfKeysKey = CacheNamespace.GetSetOfKeysKey();

            log.DebugFormat("clear cache : {0}", generationKey);

            try
            {
                var db = GetDatabase();
                var transaction = db.CreateTransaction();

                var incrementGeneration = transaction.StringIncrementAsync(generationKey);

                transaction.KeyDeleteAsync(setOfKeysKey, CommandFlags.FireAndForget);

                transaction.Execute();

                var newGeneration = transaction.Wait(incrementGeneration);
                CacheNamespace.SetHigherGeneration(newGeneration);
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not clear cache : {0}", generationKey);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
Пример #30
0
 private void OnException(RedisCacheExceptionEventArgs e)
 {
     options.OnException(e);
 }
Пример #31
0
        public virtual void Unlock(object key)
        {
            // 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.WarnFormat("attempted to unlock '{0}' but a previous lock was not acquired or timed out", key);
                return;
            }

            log.DebugFormat("releasing cache lock : {0}", lockData);

            try
            {
                var db = GetDatabase();

                var wasLockReleased = db.LockRelease(lockData.LockKey, lockData.LockValue);

                if (!wasLockReleased)
                {
                    log.WarnFormat("attempted to unlock '{0}' but it could not be relased (maybe timed out or was cleared in Redis)", lockData); 
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not release cache lock : {0}", lockData);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
 private static void DefaultOnException(RedisCacheExceptionEventArgs e)
 {
     e.Throw = true;
 }
Пример #33
0
        private void SyncInitialGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    var latestGeneration = FetchGeneration();
                    CacheNamespace.SetHigherGeneration(latestGeneration);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync initial generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) throw;
            }
        }
Пример #34
0
        public virtual void Put(object key, object value)
        {
            key.ThrowIfNull("key");
            value.ThrowIfNull("value");

            log.DebugFormat("put in cache : {0}", key);

            try
            {
                var data = serializer.Serialize(value);

                ExecuteEnsureGeneration(transaction =>
                {
                    transaction.QueueCommand(r =>
                    {
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        ((IRedisNativeClient)r).SetEx(cacheKey, expirySeconds, data);
                    });

                    transaction.QueueCommand(r =>
                    {
                        var globalKeysKey = CacheNamespace.GetGlobalKeysKey();
                        var cacheKey = CacheNamespace.GlobalCacheKey(key);
                        r.AddItemToSet(globalKeysKey, cacheKey);
                    });
                });
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not put in cache : {0}", key);

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw) { throw; }
            }
        }