Пример #1
0
        public async Task TryGetCachedResponse()
        {
            const int count = 15;

            // Clear cache
            var cache = Factory.Services.GetRequiredService <Wivuu.GlobalCache.IGlobalCache>();
            await cache.InvalidateAsync(CacheId.ForCategory("weather"));

            using var client = Factory.CreateClient();

            for (var tries = 0; tries < 3; ++tries)
            {
                var resp = await client.GetAsync($"weather/us?days={count}");

                if (client.DefaultRequestHeaders.TryGetValues("If-None-Match", out _))
                {
                    // Expect the response to be empty and not modified
                    Assert.Equal(304, (int)resp.StatusCode);
                }
                else
                {
                    var respBody = await resp.Content.ReadAsStringAsync();

                    var data = JsonConvert.DeserializeAnonymousType(respBody, new [] {
                        new {
                            Date         = default(DateTimeOffset),
                            TemperatureC = default(decimal)
                        }
                    });

                    Assert.NotNull(data);
                    Assert.Equal(count, data.Length);
                    Assert.NotEqual(default, data[0].Date);
Пример #2
0
        public async Task TestGeneralCaching(Type serializerType, Type storageProviderType)
        {
            IServiceProvider services;

            {
                var collection = new ServiceCollection();

                collection.AddWivuuGlobalCache(settings =>
                {
                    settings.RetryTimeout = TimeSpan.FromSeconds(5);

                    if (!(Activator.CreateInstance(serializerType) is ISerializationProvider serializer))
                    {
                        throw new Exception($"{serializerType} is not a serialization provider");
                    }

                    settings.SerializationProvider = serializer;

                    switch (storageProviderType.Name)
                    {
                    case nameof(BlobStorageProvider):
                        var blobServiceClient = new BlobServiceClient("UseDevelopmentStorage=true");
                        var container         = blobServiceClient.GetBlobContainerClient("globalcache");

                        container.CreateIfNotExists();

                        settings.StorageProvider = new BlobStorageProvider(container);
                        break;

                    case nameof(FileStorageProvider):
                        settings.StorageProvider = new FileStorageProvider();
                        break;

                    default:
                        throw new NotSupportedException($"{nameof(storageProviderType)} is not supported");
                    }
                });

                services = collection.BuildServiceProvider();
            }

            using (var scope = services.CreateScope())
            {
                var cache = scope.ServiceProvider.GetRequiredService <IGlobalCache>();

                // Remove item
                await cache.InvalidateAsync(CacheId.ForCategory("cachetest"));

                // Get or create item
                var item = await cache.GetOrCreateAsync(new CacheId("cachetest", "item5"), () =>
                {
                    return(Task.FromResult(new { Item = 5 }));
                });

                Assert.Equal(5, item.Item);
            }
        }
Пример #3
0
        public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var hash = CalculateHashCode(context);
            var id   = hash != 0
                ? new CacheId(CalculateCategory(context, Category), hash)
                : CacheId.ForCategory(CalculateCategory(context, Category));

            if (context.HttpContext.Items.TryGetValue(ClearCacheId, out var idsObj) &&
                idsObj is Stack <CacheId> ids)
            {
                ids.Push(id);
            }
            else
            {
                context.HttpContext.Items.TryAdd(ClearCacheId, new Stack <CacheId>(new [] { id }));
            }

            return(next());
        }
Пример #4
0
        public async Task TestStorageRemove(Type storageProviderType)
        {
            IStorageProvider store;

            switch (storageProviderType.Name)
            {
            case nameof(BlobStorageProvider):
                var blobServiceClient = new BlobServiceClient("UseDevelopmentStorage=true");
                var container         = blobServiceClient.GetBlobContainerClient("globalcache");
                await container.CreateIfNotExistsAsync();

                store = new BlobStorageProvider(container);
                break;

            case nameof(FileStorageProvider):
                store = new FileStorageProvider();
                break;

            default:
                throw new NotSupportedException($"{nameof(storageProviderType)} is not supported");
            }

            var id1 = new CacheId("remove", 1);
            var id2 = new CacheId("remove", 2);

            // Write two values
            var val1 = await OpenReadWriteAsync(id1, onWrite : stream => {
                stream.WriteByte(1);
                return(Task.FromResult(1));
            });

            var val2 = await OpenReadWriteAsync(id2, onWrite : stream => {
                stream.WriteByte(2);
                return(Task.FromResult(2));
            });

            // Clear 1 value
            Assert.True(await store.RemoveAsync(id1), "id1 should have been removed");
            await CheckRemoved(id1, 1);

            // Check 2 still exists
            Assert.Equal(val2, await OpenReadWriteAsync(id2, onRead: stream => Task.FromResult(stream.ReadByte())));

            // Clear ALL values
            Assert.True(await store.RemoveAsync(CacheId.ForCategory("remove")), "id1 and id2 should have been removed");
            await CheckRemoved(id2, 2);

            async Task CheckRemoved(CacheId id, byte notExpected)
            {
                try
                {
                    using var cts = new CancellationTokenSource();

                    cts.CancelAfter(TimeSpan.FromMilliseconds(20));

                    var value = await OpenReadWriteAsync(
                        id,
                        onRead : stream => Task.FromResult(stream.ReadByte()),
                        cancellationToken : cts.Token
                        );

                    if (value == notExpected)
                    {
                        throw new Exception($"Item {id} should have been removed");
                    }
                }
                catch (TaskCanceledException)
                {
                    // Pass
                }
            }

            async Task <T> OpenReadWriteAsync <T>(CacheId id,
                                                  Func <Stream, Task <T> >?onWrite    = null,
                                                  Func <Stream, Task <T> >?onRead     = null,
                                                  CancellationToken cancellationToken = default)