Example #1
0
        /// <inheritdoc />
        /// <summary>
        /// Sets an item into cache
        /// </summary>
        /// <typeparam name="T">The type of item</typeparam>
        /// <param name="key">Name of the item in cache</param>
        /// <param name="item">The item being set into cache</param>
        public virtual void Set <T>(string key, T item)
        {
            var expiration = DateTimeOffset.Now.AddSeconds(Options.Seconds);

            // Optionally place in L1 Cache
            if (Options.UseLocalCache)
            {
                var l1Options = new MemoryCacheEntryOptions
                {
                    AbsoluteExpiration = expiration,
                    Priority           = Options.Priority
                };
                L1Cache.Set(key, item, l1Options);
            }

            // Optionally place in L2 Cache
            if (Options.UseDistributedCache)
            {
                // If these calls fail, do nothing
                try
                {
                    var obj       = new L2CacheItem <T>(Options.Seconds, Options.Priority, item);
                    var l2Options = new DistributedCacheEntryOptions {
                        AbsoluteExpiration = expiration
                    };
                    L2Cache.Set(key, obj.ToByteArray(), l2Options);
                }
                catch { }
            }
        }
Example #2
0
        public async Task SetAsync_RemoveAsync()
        {
            var key   = "key";
            var value = new byte[] { 0x20, 0x20, 0x20, };

            var prefixedKey = $"{RedisCacheOptions.InstanceName}{key}";

            await L1L2Cache.SetAsync(key, value);

            Assert.Equal(
                value,
                await L1L2Cache.GetAsync(key));
            Assert.Equal(
                value,
                L1Cache.Get(prefixedKey));
            Assert.Equal(
                value,
                await L2Cache.GetAsync(key));

            await L1L2Cache.RemoveAsync(key);

            Assert.Null(
                await L1L2Cache.GetAsync(key));
            Assert.Null(
                L1Cache.Get(prefixedKey));
            Assert.Null(
                await L2Cache.GetAsync(key));
        }
    /// <summary>
    /// Sets a value with the given key.
    /// </summary>
    /// <param name="key">A string identifying the requested value.</param>
    /// <param name="value">The value to set in the cache.</param>
    /// <param name="distributedCacheEntryOptions">The cache options for the value.</param>
    /// <param name="cancellationToken">Optional. The System.Threading.CancellationToken used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The System.Threading.Tasks.Task that represents the asynchronous operation.</returns>
    public async Task SetAsync(
        string key,
        byte[] value,
        DistributedCacheEntryOptions distributedCacheEntryOptions,
        CancellationToken cancellationToken = default)
    {
        var semaphore = await GetOrCreateLockAsync(
            key, distributedCacheEntryOptions, cancellationToken);

        await semaphore.WaitAsync(cancellationToken);

        try
        {
            await L2Cache.SetAsync(
                key,
                value,
                distributedCacheEntryOptions,
                cancellationToken);

            SetMemoryCache(
                key, value, distributedCacheEntryOptions);
            await MessagePublisher.PublishAsync(
                key, cancellationToken);
        }
        finally
        {
            semaphore.Release();
        }
    }
Example #4
0
        public void Set_Remove()
        {
            var key   = "key";
            var value = new byte[] { 0x20, 0x20, 0x20, };

            var prefixedKey = $"{RedisCacheOptions.InstanceName}{key}";

            L1L2Cache.Set(key, value);

            Assert.Equal(
                value,
                L1L2Cache.Get(key));
            Assert.Equal(
                value,
                L1Cache.Get(prefixedKey));
            Assert.Equal(
                value,
                L2Cache.Get(key));

            L1L2Cache.Remove(key);

            Assert.Null(
                L1L2Cache.Get(key));
            Assert.Null(
                L1Cache.Get(prefixedKey));
            Assert.Null(
                L2Cache.Get(key));
        }
Example #5
0
        /// <inheritdoc />
        /// <summary>
        /// Sets an item into cache
        /// </summary>
        /// <typeparam name="T">The type of item</typeparam>
        /// <param name="key">Name of the item in cache</param>
        /// <param name="item">The item being set into cache</param>
        public virtual void Set <T>(string key, T item)
        {
            var expiration = DateTimeOffset.Now.AddSeconds(Options.Seconds);

            // If these calls fail, do nothing
            try
            {
                var obj       = new L2CacheItem <T>(Options.Seconds, Options.Priority, item);
                var l2Options = new DistributedCacheEntryOptions {
                    AbsoluteExpiration = expiration
                };
                L2Cache.Set(key, obj.ToByteArray(), l2Options);
            }
            catch { }
        }
Example #6
0
        /// <inheritdoc />
        /// <summary>
        /// Retrieves an item from the Cache
        /// </summary>
        /// <typeparam name="T">The type of item</typeparam>
        /// <param name="key">Name of the item in cache</param>
        /// <param name="item">If the object is not found in the Cache, this will be populated</param>
        /// <returns>True if the object was found, False if not found</returns>
        public virtual bool Get <T>(string key, out T item)
        {
            // If in L1 cache, just return it
            if (Options.UseLocalCache && L1Cache.TryGetValue(key, out item))
            {
                return(true);
            }

            // Check L2 cache
            if (Options.UseDistributedCache)
            {
                byte[] bytes = null;
                try
                {
                    bytes = L2Cache.Get(key);
                }
                catch { }

                // Was not found
                if (bytes == null)
                {
                    item = default;
                    return(false);
                }

                // Object was found
                var obj = bytes.FromByteArray <L2CacheItem <T> >();
                item = obj.Item;

                // Store the object back into L1 cache
                // ReSharper disable once InvertIf
                if (Options.UseLocalCache)
                {
                    var options = new MemoryCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = obj.RemainingCacheTime(),
                        Priority = obj.Priority
                    };
                    L1Cache.Set(key, item, options);
                }

                // Return it now
                return(true);
            }

            item = default;
            return(false);
        }
Example #7
0
 public Piledriver()
 {
     monitoringConfigs     = new MonitoringConfig[11];
     monitoringConfigs[0]  = new BpuMonitoringConfig(this);
     monitoringConfigs[1]  = new IFetch(this);
     monitoringConfigs[2]  = new DataCache(this);
     monitoringConfigs[3]  = new DataCache1(this);
     monitoringConfigs[4]  = new L2Cache(this);
     monitoringConfigs[5]  = new DispatchStall(this);
     monitoringConfigs[6]  = new DispatchStall1(this);
     monitoringConfigs[7]  = new DispatchStallFP(this);
     monitoringConfigs[8]  = new DispatchStallMisc(this);
     monitoringConfigs[9]  = new DTLB(this);
     monitoringConfigs[10] = new FPU(this);
     architectureName      = "Piledriver";
 }
    /// <summary>
    /// Removes the value with the given key.
    /// </summary>
    /// <param name="key">A string identifying the requested value.</param>
    public void Remove(string key)
    {
        var semaphore = GetOrCreateLock(key, null);

        semaphore.Wait();
        try
        {
            L2Cache.Remove(key);
            L1Cache.Remove(
                $"{L1L2RedisCacheOptions.KeyPrefix}{key}");
            MessagePublisher.Publish(key);
            L1Cache.Remove(
                $"{L1L2RedisCacheOptions.LockKeyPrefix}{key}");
        }
        finally
        {
            semaphore.Release();
        }
    }
    /// <summary>
    /// Sets a value with the given key.
    /// </summary>
    /// <param name="key">A string identifying the requested value.</param>
    /// <param name="value">The value to set in the cache.</param>
    /// <param name="distributedCacheEntryOptions">The cache options for the value.</param>
    public void Set(
        string key,
        byte[] value,
        DistributedCacheEntryOptions distributedCacheEntryOptions)
    {
        var semaphore = GetOrCreateLock(
            key, distributedCacheEntryOptions);

        semaphore.Wait();
        try
        {
            L2Cache.Set(
                key, value, distributedCacheEntryOptions);
            SetMemoryCache(
                key, value, distributedCacheEntryOptions);
            MessagePublisher.Publish(key);
        }
        finally
        {
            semaphore.Release();
        }
    }
Example #10
0
        /// <inheritdoc />
        /// <summary>
        /// Retrieves an item from the Cache
        /// </summary>
        /// <typeparam name="T">The type of item</typeparam>
        /// <param name="key">Name of the item in cache</param>
        /// <param name="item">If the object is not found in the Cache, this will be populated</param>
        /// <returns>True if the object was found, False if not found</returns>
        public virtual bool Get <T>(string key, out T item)
        {
            byte[] bytes = null;
            try
            {
                bytes = L2Cache.Get(key);
            }
            catch { }

            // Was not found
            if (bytes == null)
            {
                item = default;
                return(false);
            }

            // Object was found
            var obj = bytes.FromByteArray <L2CacheItem <T> >();

            item = obj.Item;
            return(true);
        }
Example #11
0
    /// <summary>
    /// Removes the value with the given key.
    /// </summary>
    /// <param name="key">A string identifying the requested value.</param>
    /// <param name="cancellationToken">Optional. The System.Threading.CancellationToken used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The System.Threading.Tasks.Task that represents the asynchronous operation.</returns>
    public async Task RemoveAsync(
        string key,
        CancellationToken cancellationToken = default)
    {
        var semaphore = await GetOrCreateLockAsync(
            key, null, cancellationToken);

        await semaphore.WaitAsync(cancellationToken);

        try
        {
            L2Cache.Remove(key);
            L1Cache.Remove(
                $"{L1L2RedisCacheOptions.KeyPrefix}{key}");
            MessagePublisher.Publish(key);
            L1Cache.Remove(
                $"{L1L2RedisCacheOptions.LockKeyPrefix}{key}");
        }
        finally
        {
            semaphore.Release();
        }
    }
Example #12
0
 /// <summary>
 /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).
 /// </summary>
 /// <param name="key">A string identifying the requested value.</param>
 /// <param name="cancellationToken">Optional. The System.Threading.CancellationToken used to propagate notifications that the operation should be canceled.</param>
 /// <returns>The System.Threading.Tasks.Task that represents the asynchronous operation.</returns>
 public async Task RefreshAsync(
     string key,
     CancellationToken cancellationToken = default)
 {
     await L2Cache.RefreshAsync(key, cancellationToken);
 }
Example #13
0
 /// <summary>
 /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).
 /// </summary>
 /// <param name="key">A string identifying the requested value.</param>
 public void Refresh(string key)
 {
     L2Cache.Refresh(key);
 }
    public async Task Performance_Test(
        int iterations)
    {
        Stopwatch.Restart();
        for (var iteration = 1; iteration <= iterations; iteration++)
        {
            await L2Cache.SetStringAsync(
                $"Performance:{iteration}",
                "Value",
                new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow =
                    TimeSpan.FromMinutes(5),
            });
        }
        Stopwatch.Stop();
        var l2SetTicks = Stopwatch.ElapsedTicks;

        Stopwatch.Restart();
        for (var iteration = 1; iteration <= iterations; iteration++)
        {
            await L1L2Cache.GetStringAsync(
                $"Performance:{iteration}");
        }
        Stopwatch.Stop();
        var l1L2GetPropagationTicks = Stopwatch.ElapsedTicks;

        Stopwatch.Restart();
        for (var iteration = 1; iteration <= iterations; iteration++)
        {
            await L1L2Cache.SetStringAsync(
                $"Performance:{iteration}",
                "Value",
                new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow =
                    TimeSpan.FromMinutes(5),
            });
        }
        Stopwatch.Stop();
        var l1L2SetTicks = Stopwatch.ElapsedTicks;

        Stopwatch.Restart();
        for (var iteration = 1; iteration <= iterations; iteration++)
        {
            await L2Cache.GetStringAsync(
                $"Performance:{iteration}");
        }
        Stopwatch.Stop();
        var l2GetTicks = Stopwatch.ElapsedTicks;

        Stopwatch.Restart();
        for (var iteration = 1; iteration <= iterations; iteration++)
        {
            await L1L2Cache.GetStringAsync(
                $"Performance:{iteration}");
        }
        Stopwatch.Stop();
        var l1L2GetTicks = Stopwatch.ElapsedTicks;

        Assert.True(
            l1L2SetTicks / l2SetTicks < 3,
            "L1L2Cache Set cannot perform significantly worse than RedisCache Set.");

        Assert.True(
            l2GetTicks / l1L2GetTicks > 100,
            "L1L2Cache Get must perform significantly better than RedisCache Get.");

        Assert.True(
            l1L2GetPropagationTicks / l2GetTicks < 3,
            "L1L2Cache Get with propagation cannot perform significantly worse than RedisCache Get.");
    }
Example #15
0
        public L1L2RedisCacheTest()
        {
            var mockConnectionMultiplexer = new Mock <IConnectionMultiplexer>();

            var mockDatabase = new Mock <IDatabase>();

            mockDatabase
            .Setup(
                d => d.HashGetAll(
                    It.IsAny <RedisKey>(),
                    It.IsAny <CommandFlags>()))
            .Returns <RedisKey, CommandFlags>(
                (k, cF) =>
            {
                var key = ((string)k).Substring(
                    RedisCacheOptions.InstanceName?.Length ?? 0);
                var value = L2Cache.Get(key);
                return(new HashEntry[]
                {
                    new HashEntry("data", value),
                });
            });
            mockDatabase
            .Setup(
                d => d.KeyExists(
                    It.IsAny <RedisKey>(),
                    It.IsAny <CommandFlags>()))
            .Returns <RedisKey, CommandFlags>(
                (k, cF) => L2Cache.Get(k) != null);
            mockDatabase
            .Setup(
                d => d.KeyExistsAsync(
                    It.IsAny <RedisKey>(),
                    It.IsAny <CommandFlags>()))
            .Returns <RedisKey, CommandFlags>(
                async(k, cF) =>
            {
                var key = ((string)k).Substring(
                    RedisCacheOptions.InstanceName?.Length ?? 0);
                return(await L2Cache.GetAsync(key) != null);
            });

            var mockSubscriber = new Mock <ISubscriber>();

            mockSubscriber
            .Setup(
                s => s.Subscribe(
                    It.IsAny <RedisChannel>(),
                    It.IsAny <Action <RedisChannel, RedisValue> >(),
                    It.IsAny <CommandFlags>()));

            mockConnectionMultiplexer
            .Setup(cM => cM.GetDatabase(It.IsAny <int>(), It.IsAny <object>()))
            .Returns(mockDatabase.Object);
            mockConnectionMultiplexer
            .Setup(cM => cM.GetSubscriber(It.IsAny <object>()))
            .Returns(mockSubscriber.Object);

            L1Cache = new MemoryCache(
                Options.Create <MemoryCacheOptions>(
                    new MemoryCacheOptions()));

            L2Cache = new MemoryDistributedCache(
                Options.Create <MemoryDistributedCacheOptions>(
                    new MemoryDistributedCacheOptions()));

            var jsonSerializerOptions = Options.Create <JsonSerializerOptions>(
                new JsonSerializerOptions());

            var redisCacheOptionsAccessor = Options.Create <RedisCacheOptions>(
                new RedisCacheOptions
            {
                InstanceName = "InstanceName.",
            });

            RedisCacheOptions = redisCacheOptionsAccessor.Value;

            L1L2Cache = new L1L2RedisCache(
                mockConnectionMultiplexer.Object,
                new Func <IDistributedCache>(() => L2Cache),
                jsonSerializerOptions,
                L1Cache,
                RedisCacheOptions);
        }