Пример #1
0
        public void DistributedCacheCircuitBreakerActuallyWorks()
        {
            var circuitBreakerDuration = TimeSpan.FromSeconds(2);
            var distributedCache       = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache  = new ChaosDistributedCache(distributedCache);

            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions()
                {
                    DistributedCacheCircuitBreakerDuration = circuitBreakerDuration
                }, memoryCache))
                {
                    fusionCache.DefaultEntryOptions.AllowBackgroundDistributedCacheOperations = false;
                    fusionCache.SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer());

                    fusionCache.Set <int>("foo", 1, options => options.SetDurationSec(60).SetFailSafe(true));
                    chaosDistributedCache.SetAlwaysThrow();
                    fusionCache.Set <int>("foo", 2, options => options.SetDurationSec(60).SetFailSafe(true));
                    chaosDistributedCache.SetNeverThrow();
                    fusionCache.Set <int>("foo", 3, options => options.SetDurationSec(60).SetFailSafe(true));
                    Thread.Sleep(circuitBreakerDuration);
                    memoryCache.Remove("foo");
                    var res = fusionCache.GetOrDefault <int>("foo", -1);

                    Assert.Equal(1, res);
                }
            }
        }
Пример #2
0
        public void FusionCacheCache()
        {
            using (var cache = new FusionCache(new FusionCacheOptions {
                DefaultEntryOptions = new FusionCacheEntryOptions(CacheDuration)
            }))
            {
                for (int i = 0; i < Rounds; i++)
                {
                    FactoryCallsCount = 0;

                    // FULL PARALLEL
                    Parallel.ForEach(Keys, key =>
                    {
                        Parallel.For(0, Accessors, _ =>
                        {
                            cache.GetOrSet <long>(
                                key,
                                ct =>
                            {
                                Interlocked.Increment(ref FactoryCallsCount);
                                Thread.Sleep(FactoryDurationMs);
                                return(DateTimeOffset.UtcNow.Ticks);
                            }
                                );
                        });
                    });

                    UpdateExcessiveFactoryCallsStatistics(GetCallerName(), KeysCount, FactoryCallsCount);
                }

                // NO NEED TO CLEANUP, AUTOMATICALLY DONE WHEN DISPOSING
            }
        }
Пример #3
0
        public async Task OnlyOneFactoryGetsCalledEvenInHighConcurrencyAsync(int accessorsCount)
        {
            using (var cache = new FusionCache(new FusionCacheOptions()))
            {
                var factoryCallsCount = 0;

                var tasks = new ConcurrentBag <Task>();
                Parallel.For(0, accessorsCount, _ =>
                {
                    var task = cache.GetOrSetAsync <int>(
                        "foo",
                        async _ =>
                    {
                        Interlocked.Increment(ref factoryCallsCount);
                        return(42);
                    },
                        new FusionCacheEntryOptions(TimeSpan.FromSeconds(10))
                        );
                    tasks.Add(task);
                });

                await Task.WhenAll(tasks);

                Assert.Equal(1, factoryCallsCount);
            }
        }
        public async Task DistributedCacheCircuitBreakerActuallyWorksAsync(SerializerType serializerType)
        {
            var circuitBreakerDuration = TimeSpan.FromSeconds(2);
            var distributedCache       = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache  = new ChaosDistributedCache(distributedCache);

            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions()
                {
                    DistributedCacheCircuitBreakerDuration = circuitBreakerDuration
                }, memoryCache))
                {
                    fusionCache.DefaultEntryOptions.AllowBackgroundDistributedCacheOperations = false;
                    fusionCache.SetupDistributedCache(chaosDistributedCache, GetSerializer(serializerType));

                    await fusionCache.SetAsync <int>("foo", 1, options => options.SetDurationSec(60).SetFailSafe(true));

                    chaosDistributedCache.SetAlwaysThrow();
                    await fusionCache.SetAsync <int>("foo", 2, options => options.SetDurationSec(60).SetFailSafe(true));

                    chaosDistributedCache.SetNeverThrow();
                    await fusionCache.SetAsync <int>("foo", 3, options => options.SetDurationSec(60).SetFailSafe(true));

                    await Task.Delay(circuitBreakerDuration).ConfigureAwait(false);

                    memoryCache.Remove("foo");
                    var res = await fusionCache.GetOrDefaultAsync <int>("foo", -1);

                    Assert.Equal(1, res);
                }
            }
        }
Пример #5
0
        public async Task FusionCache()
        {
            using (var cache = new FusionCache(new FusionCacheOptions {
                DefaultEntryOptions = new FusionCacheEntryOptions(CacheDuration)
            }))
            {
                for (int i = 0; i < Rounds; i++)
                {
                    var tasks = new ConcurrentBag <Task>();

                    Parallel.ForEach(Keys, key =>
                    {
                        Parallel.For(0, Accessors, _ =>
                        {
                            var t = cache.GetOrSetAsync <SamplePayload>(
                                key,
                                async ct =>
                            {
                                await Task.Delay(FactoryDurationMs).ConfigureAwait(false);
                                return(new SamplePayload());
                            }
                                );
                            tasks.Add(t);
                        });
                    });

                    await Task.WhenAll(tasks).ConfigureAwait(false);
                }

                // NO NEED TO CLEANUP, AUTOMATICALLY DONE WHEN DISPOSING
            }
        }
Пример #6
0
        public async Task AppliesDistributedCacheSoftTimeoutAsync()
        {
            var simulatedDelayMs      = 5_000;
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            chaosDistributedCache.SetAlwaysDelayExactly(TimeSpan.FromMilliseconds(simulatedDelayMs));
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache))
                {
                    fusionCache.SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer());
                    await fusionCache.SetAsync <int>("foo", 42, new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true));

                    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

                    var sw  = Stopwatch.StartNew();
                    var res = await fusionCache.GetOrSetAsync <int>("foo", async ct => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true).SetDistributedCacheTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1_000)));

                    sw.Stop();

                    Assert.Equal(42, res);
                    Assert.True(sw.ElapsedMilliseconds >= 100, "Distributed cache soft timeout not applied");
                    Assert.True(sw.ElapsedMilliseconds < simulatedDelayMs, "Distributed cache soft timeout not applied");
                }
            }
        }
Пример #7
0
        public async Task HandlesDistributedCacheFailuresInTheMiddleOfAnOperationAsync()
        {
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
                var chaosDistributedCache = new ChaosDistributedCache(distributedCache);
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache).SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer()))
                {
                    var task = fusionCache.GetOrSetAsync <int>("foo", async _ => { await Task.Delay(2_000); return(42); }, new FusionCacheEntryOptions(TimeSpan.FromSeconds(10)));
                    await Task.Delay(500);

                    chaosDistributedCache.SetAlwaysThrow();
                    var value = await task;
                    chaosDistributedCache.SetNeverThrow();

                    // END RESULT IS WHAT EXPECTED
                    Assert.Equal(42, value);

                    // MEMORY CACHE HAS BEEN UPDATED
                    Assert.Equal(42, memoryCache.Get <FusionCacheEntry <int> >("foo").Value);

                    // DISTRIBUTED CACHE HAS -NOT- BEEN UPDATED
                    Assert.Null(distributedCache.GetString("foo"));
                }
            }
        }
Пример #8
0
        public void FusionCache()
        {
            using (var cache = new FusionCache(new FusionCacheOptions {
                DefaultEntryOptions = new FusionCacheEntryOptions(CacheDuration)
            }))
            {
                for (int i = 0; i < Rounds; i++)
                {
                    Parallel.ForEach(Keys, key =>
                    {
                        Parallel.For(0, Accessors, _ =>
                        {
                            cache.GetOrSet <SamplePayload>(
                                key,
                                ct =>
                            {
                                Thread.Sleep(FactoryDurationMs);
                                return(new SamplePayload());
                            }
                                );
                        });
                    });
                }

                // NO NEED TO CLEANUP, AUTOMATICALLY DONE WHEN DISPOSING
            }
        }
 public void ThrowsOnFactoryHardTimeoutWithoutStaleData()
 {
     using (var cache = new FusionCache(new FusionCacheOptions()))
     {
         Assert.Throws <SyntheticTimeoutException>(() =>
         {
             var value = cache.GetOrSet <int>("foo", _ => { Thread.Sleep(1_000); return(21); }, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true).SetFactoryTimeoutsMs(2_000, 100));
         });
Пример #10
0
        /// <summary>
        /// Adds the standard implementation of <see cref="IFusionCache"/> to the <see cref="IServiceCollection" />.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
        /// <param name="setupOptionsAction">The <see cref="Action{FusionCacheOptions}"/> to configure the provided <see cref="FusionCacheOptions"/>.</param>
        /// <param name="useDistributedCacheIfAvailable">Automatically wires up an <see cref="IDistributedCache"/> if it has been registered in the Dependendy Injection container </param>
        /// <param name="ignoreMemoryDistributedCache">If the registered <see cref="IDistributedCache"/> found is an instance of <see cref="MemoryDistributedCache"/> (typical when using asp.net) it will be ignored, since it is completely useless (and will consume cpu and memory).</param>
        /// <param name="setupCacheAction">The <see cref="Action{IServiceProvider,FusionCacheOptions}"/> to configure the newly created <see cref="IFusionCache"/> instance.</param>
        /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
        public static IServiceCollection AddFusionCache(this IServiceCollection services, Action <FusionCacheOptions>?setupOptionsAction = null, bool useDistributedCacheIfAvailable = true, bool ignoreMemoryDistributedCache = true, Action <IServiceProvider, IFusionCache>?setupCacheAction = null)
        {
            if (services is null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services.AddOptions();

            if (setupOptionsAction is object)
            {
                services.Configure(setupOptionsAction);
            }

            services.TryAdd(ServiceDescriptor.Singleton <IFusionCache>(serviceProvider =>
            {
                var logger = serviceProvider.GetService <ILogger <FusionCache> >();

                var cache = new FusionCache(
                    serviceProvider.GetRequiredService <IOptions <FusionCacheOptions> >(),
                    serviceProvider.GetService <IMemoryCache>(),
                    logger: logger
                    );

                if (useDistributedCacheIfAvailable)
                {
                    var distributedCache = serviceProvider.GetService <IDistributedCache>();

                    if (ignoreMemoryDistributedCache && distributedCache is MemoryDistributedCache)
                    {
                        distributedCache = null;
                    }

                    if (distributedCache is object)
                    {
                        var serializer = serviceProvider.GetService <IFusionCacheSerializer>();

                        if (serializer is null)
                        {
                            if (logger?.IsEnabled(LogLevel.Warning) ?? false)
                            {
                                logger.LogWarning("FUSION: a usable implementation of IDistributedCache was found (CACHE={DistributedCacheType}) but no implementation of IFusionCacheSerializer was found, so the distributed cache subsystem has not been set up", distributedCache.GetType().FullName);
                            }
                        }
                        else
                        {
                            cache.SetupDistributedCache(distributedCache, serializer);
                        }
                    }
                }

                setupCacheAction?.Invoke(serviceProvider, cache);

                return(cache);
            }));

            return(services);
        }
 public async Task ThrowsOnFactoryHardTimeoutWithoutStaleDataAsync()
 {
     using (var cache = new FusionCache(new FusionCacheOptions()))
     {
         await Assert.ThrowsAsync <SyntheticTimeoutException>(async() =>
         {
             var value = await cache.GetOrSetAsync <int>("foo", async _ => { await Task.Delay(1_000); return(21); }, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true).SetFactoryTimeoutsMs(2_000, 100));
         });
     }
 }
 public void ReturnsStaleDataWhenFactoryFailsWithFailSafe()
 {
     using (var cache = new FusionCache(new FusionCacheOptions()))
     {
         var initialValue = cache.GetOrSet <int>("foo", _ => 42, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true));
         Thread.Sleep(1_100);
         var newValue = cache.GetOrSet <int>("foo", _ => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true));
         Assert.Equal(initialValue, newValue);
     }
 }
        public async Task FusionCache_MemoryProviderAsync()
        {
            var fusionCache = new FusionCache(new FusionCacheOptions());

            await LoopActionAsync(Iterations, async() =>
            {
                await fusionCache.SetAsync("TestKey", 123, TimeSpan.FromDays(1));
                await fusionCache.GetOrDefaultAsync <int>("TestKey");
                await fusionCache.GetOrSetAsync("TestKey", (cancellationToken) => Task.FromResult("Hello World"), TimeSpan.FromDays(1));
            });
        }
        public void FusionCache_MemoryProvider()
        {
            var fusionCache = new FusionCache(new FusionCacheOptions());

            LoopAction(Iterations, () =>
            {
                fusionCache.Set("TestKey", 123, TimeSpan.FromDays(1));
                fusionCache.GetOrDefault <int>("TestKey");
                fusionCache.GetOrSet("TestKey", (cancellationToken) => "Hello World", TimeSpan.FromDays(1));
            });
        }
        public async Task ReturnsStaleDataWhenFactoryFailsWithFailSafeAsync()
        {
            using (var cache = new FusionCache(new FusionCacheOptions()))
            {
                var initialValue = await cache.GetOrSetAsync <int>("foo", async _ => 42, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true));

                await Task.Delay(1_100);

                var newValue = await cache.GetOrSetAsync <int>("foo", async _ => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true));

                Assert.Equal(initialValue, newValue);
            }
        }
        public async Task ThrowsWhenFactoryThrowsWithoutFailSafeAsync()
        {
            using (var cache = new FusionCache(new FusionCacheOptions()))
            {
                var initialValue = await cache.GetOrSetAsync <int>("foo", async _ => 42, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(true));

                await Task.Delay(1_100);

                await Assert.ThrowsAnyAsync <Exception>(async() =>
                {
                    var newValue = await cache.GetOrSetAsync <int>("foo", async _ => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)).SetFailSafe(false));
                });
            }
        }
 public void HandlesFlexibleComplexTypeConversions(SerializerType serializerType)
 {
     using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
     {
         var distributedCache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
         using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache).SetupDistributedCache(distributedCache, GetSerializer(serializerType)))
         {
             var initialValue = (object)SampleComplexObject.CreateRandom();
             fusionCache.Set("foo", initialValue, TimeSpan.FromHours(24));
             memoryCache.Remove("foo");
             var newValue = fusionCache.GetOrDefault <SampleComplexObject>("foo");
             Assert.NotNull(newValue);
         }
     }
 }
Пример #18
0
 public CacheAlternatives_Memory_Parallel_Benchmark()
 {
     CacheTower   = new CacheStack(new[] { new MemoryCacheLayer() }, Array.Empty <ICacheExtension>());
     CacheManager = CacheFactory.Build <string>(b =>
     {
         b.WithMicrosoftMemoryCacheHandle();
     });
     EasyCaching = new DefaultInMemoryCachingProvider(
         "EasyCaching",
         new[] { new InMemoryCaching("EasyCaching", new InMemoryCachingOptions()) },
         new InMemoryOptions()
         );
     LazyCache   = new CachingService();
     FusionCache = new FusionCache(new FusionCacheOptions());
 }
Пример #19
0
        public async Task HandlesDistributedCacheRemovalInTheMiddleOfAnOperationAsync()
        {
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            using (var fusionCache = new FusionCache(new FusionCacheOptions()).SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer()))
            {
                var task = fusionCache.GetOrSetAsync <int>("foo", async _ => { await Task.Delay(2_000); return(42); }, new FusionCacheEntryOptions(TimeSpan.FromSeconds(10)));
                await Task.Delay(500);

                fusionCache.RemoveDistributedCache();
                var value = await task;
                Assert.Equal(42, value);
            }
        }
Пример #20
0
        public async Task ReturnsDataFromDistributedCacheIfNoDataInMemoryCacheAsync()
        {
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                var distributedCache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache).SetupDistributedCache(distributedCache, new FusionCacheNewtonsoftJsonSerializer()))
                {
                    var initialValue = await fusionCache.GetOrSetAsync <int>("foo", _ => Task.FromResult(42), new FusionCacheEntryOptions().SetDurationSec(10));

                    memoryCache.Remove("foo");
                    var newValue = await fusionCache.GetOrSetAsync <int>("foo", _ => Task.FromResult(21), new FusionCacheEntryOptions().SetDurationSec(10));

                    Assert.Equal(initialValue, newValue);
                }
            }
        }
Пример #21
0
        public void ReturnsDataFromDistributedCacheIfNoDataInMemoryCache()
        {
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                var distributedCache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache).SetupDistributedCache(distributedCache, new FusionCacheNewtonsoftJsonSerializer()))
                {
                    fusionCache.DefaultEntryOptions.AllowBackgroundDistributedCacheOperations = false;

                    var initialValue = fusionCache.GetOrSet <int>("foo", _ => 42, options => options.SetDurationSec(10));
                    memoryCache.Remove("foo");
                    var newValue = fusionCache.GetOrSet <int>("foo", _ => 21, options => options.SetDurationSec(10));
                    Assert.Equal(initialValue, newValue);
                }
            }
        }
        public async Task HandlesFlexibleSimpleTypeConversionsAsync(SerializerType serializerType)
        {
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                var distributedCache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache).SetupDistributedCache(distributedCache, GetSerializer(serializerType)))
                {
                    var initialValue = (object)42;
                    await fusionCache.SetAsync("foo", initialValue, TimeSpan.FromHours(24));

                    memoryCache.Remove("foo");
                    var newValue = await fusionCache.GetOrDefaultAsync <int>("foo");

                    Assert.Equal(initialValue, newValue);
                }
            }
        }
 public void ThrowsWhenFactoryThrowsWithoutFailSafe()
 {
     using (var cache = new FusionCache(new FusionCacheOptions()))
     {
         var initialValue = cache.GetOrSet <int>("foo", _ => 42, new FusionCacheEntryOptions(TimeSpan.FromSeconds(1))
         {
             IsFailSafeEnabled = true
         });
         Thread.Sleep(1_100);
         Assert.ThrowsAny <Exception>(() =>
         {
             var newValue = cache.GetOrSet <int>("foo", _ => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions(TimeSpan.FromSeconds(1))
             {
                 IsFailSafeEnabled = false
             });
         });
     }
 }
Пример #24
0
        public async Task OnlyOneFactoryGetsCalledEvenInMixedHighConcurrencyAsync(int accessorsCount)
        {
            using (var cache = new FusionCache(new FusionCacheOptions()))
            {
                var factoryCallsCount = 0;

                var tasks = new ConcurrentBag <Task>();
                Parallel.For(0, accessorsCount, idx =>
                {
                    if (idx % 2 == 0)
                    {
                        var task = cache.GetOrSetAsync <int>(
                            "foo",
                            async _ =>
                        {
                            Interlocked.Increment(ref factoryCallsCount);
                            await Task.Delay(FactoryDuration).ConfigureAwait(false);
                            return(42);
                        },
                            new FusionCacheEntryOptions(TimeSpan.FromSeconds(10))
                            );
                        tasks.Add(task);
                    }
                    else
                    {
                        cache.GetOrSet <int>(
                            "foo",
                            _ =>
                        {
                            Interlocked.Increment(ref factoryCallsCount);
                            Thread.Sleep(FactoryDuration);
                            return(42);
                        },
                            new FusionCacheEntryOptions(TimeSpan.FromSeconds(10))
                            );
                    }
                });

                await Task.WhenAll(tasks);

                Assert.Equal(1, factoryCallsCount);
            }
        }
Пример #25
0
        public async Task HandlesDistributedCacheFailuresAsync()
        {
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            using (var fusionCache = new FusionCache(new FusionCacheOptions()).SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer()))
            {
                var initialValue = await fusionCache.GetOrSetAsync <int>("foo", _ => Task.FromResult(42), new FusionCacheEntryOptions()
                {
                    Duration = TimeSpan.FromSeconds(1), IsFailSafeEnabled = true
                });

                await Task.Delay(1_500);

                chaosDistributedCache.SetAlwaysThrow();
                var newValue = await fusionCache.GetOrSetAsync <int>("foo", async _ => throw new Exception("Generic error"), new FusionCacheEntryOptions(TimeSpan.FromSeconds(1)) { IsFailSafeEnabled = true });;
                Assert.Equal(initialValue, newValue);
            }
        }
Пример #26
0
        public void AppliesDistributedCacheHardTimeout()
        {
            var simulatedDelayMs      = 5_000;
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            chaosDistributedCache.SetAlwaysDelayExactly(TimeSpan.FromMilliseconds(simulatedDelayMs));
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache))
                {
                    fusionCache.SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer());
                    fusionCache.Set <int>("foo", 42, new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true));
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    memoryCache.Remove("foo");
                    Assert.Throws <Exception>(() =>
                    {
                        _ = fusionCache.GetOrSet <int>("foo", ct => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true).SetDistributedCacheTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1_000)));
                    });
                }
            }
        }
Пример #27
0
        public void OnlyOneFactoryGetsCalledEvenInHighConcurrency(int accessorsCount)
        {
            using (var cache = new FusionCache(new FusionCacheOptions()))
            {
                var factoryCallsCount = 0;

                var tasks = new ConcurrentBag <Task>();
                Parallel.For(0, accessorsCount, _ =>
                {
                    cache.GetOrSet <int>(
                        "foo",
                        _ =>
                    {
                        Interlocked.Increment(ref factoryCallsCount);
                        return(42);
                    },
                        new FusionCacheEntryOptions(TimeSpan.FromSeconds(10))
                        );
                });

                Assert.Equal(1, factoryCallsCount);
            }
        }
Пример #28
0
        public async Task FusionCacheCache()
        {
            using (var cache = new FusionCache(new FusionCacheOptions {
                DefaultEntryOptions = new FusionCacheEntryOptions(CacheDuration)
            }))
            {
                for (int i = 0; i < Rounds; i++)
                {
                    var tasks = new ConcurrentBag <Task>();
                    FactoryCallsCount = 0;

                    // FULL PARALLEL
                    Parallel.ForEach(Keys, key =>
                    {
                        Parallel.For(0, Accessors, _ =>
                        {
                            var t = cache.GetOrSetAsync <long>(
                                key,
                                async ct =>
                            {
                                Interlocked.Increment(ref FactoryCallsCount);
                                await Task.Delay(FactoryDurationMs).ConfigureAwait(false);
                                return(DateTimeOffset.UtcNow.Ticks);
                            }
                                );
                            tasks.Add(t);
                        });
                    });

                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    UpdateExcessiveFactoryCallsStatistics(GetCallerName(), KeysCount, FactoryCallsCount);
                }

                // NO NEED TO CLEANUP, AUTOMATICALLY DONE WHEN DISPOSING
            }
        }
        public void AppliesDistributedCacheSoftTimeout(SerializerType serializerType)
        {
            var simulatedDelayMs      = 5_000;
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            chaosDistributedCache.SetAlwaysDelayExactly(TimeSpan.FromMilliseconds(simulatedDelayMs));
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache))
                {
                    fusionCache.SetupDistributedCache(chaosDistributedCache, GetSerializer(serializerType));
                    fusionCache.Set <int>("foo", 42, new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true));
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    var sw  = Stopwatch.StartNew();
                    var res = fusionCache.GetOrSet <int>("foo", ct => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true).SetDistributedCacheTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1_000)));
                    sw.Stop();

                    Assert.Equal(42, res);
                    Assert.True(sw.ElapsedMilliseconds >= 100, "Distributed cache soft timeout not applied");
                    Assert.True(sw.ElapsedMilliseconds < simulatedDelayMs, "Distributed cache soft timeout not applied");
                }
            }
        }
Пример #30
0
        public async Task AppliesDistributedCacheHardTimeoutAsync()
        {
            var simulatedDelayMs      = 5_000;
            var distributedCache      = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
            var chaosDistributedCache = new ChaosDistributedCache(distributedCache);

            chaosDistributedCache.SetAlwaysDelayExactly(TimeSpan.FromMilliseconds(simulatedDelayMs));
            using (var memoryCache = new MemoryCache(new MemoryCacheOptions()))
            {
                using (var fusionCache = new FusionCache(new FusionCacheOptions(), memoryCache))
                {
                    fusionCache.SetupDistributedCache(chaosDistributedCache, new FusionCacheNewtonsoftJsonSerializer());
                    await fusionCache.SetAsync <int>("foo", 42, new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true));

                    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

                    memoryCache.Remove("foo");
                    await Assert.ThrowsAsync <Exception>(async() =>
                    {
                        var res = await fusionCache.GetOrSetAsync <int>("foo", async ct => throw new Exception("Sloths are cool"), new FusionCacheEntryOptions().SetDurationSec(1).SetFailSafe(true).SetDistributedCacheTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1_000)));
                    });
                }
            }
        }