Coder Social home page Coder Social logo

app-vnext / polly.caching.idistributedcache Goto Github PK

View Code? Open in Web Editor NEW
29.0 17.0 11.0 82 KB

Plug-in for the Polly Cache policy supporting Microsoft.Extensions.Caching.Distributed.IDistributedCache.

License: Other

Batchfile 0.15% C# 94.86% PowerShell 4.99%
resilience resiliency-patterns caching dotnet-core dotnetcore polly

polly.caching.idistributedcache's Introduction

Polly.Caching.Distributed

This repo contains the Microsoft.Extensions.Caching.Distributed.IDistributedCache provider for the Polly Cache policy. The current version targets .NET Standard 1.1, .NET Standard 2.0 and .NET Standard 2.1.

NuGet version Build status Slack Status

What is Polly?

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, Cache aside and Fallback in a fluent and thread-safe manner.

Polly is a member of the .NET Foundation.

Keep up to date with new feature announcements, tips & tricks, and other news through www.thepollyproject.org

What is Polly.Caching.Distributed?

This project, Polly.Caching.Distributed, allows you to use Polly's CachePolicy with implementations of .Net Standard's IDistributedCache.

Installing Polly.Caching.Distributed via NuGet

Install-Package Polly.Caching.Distributed

Supported targets

Polly.Caching.Distributed >= v3.0.1 supports .NET Standard 1.1, .NET Standard 2.0 and .NET Standard 2.1.

Polly.Caching.Distributed < v3.0.1 supports .NET Standard 1.1 and .NET Standard 2.0.

Dependency compatibility with Polly

Polly.Caching.Distributed >=v3.0.1 requires:

Polly.Caching.Distributed v3.0.0 requires:

Polly.Caching.Distributed >=v2.0 and <v3 requires:

  • Polly >= v6.0.1 and <v7.

Polly.Caching.IDistributedCache <v2.0 requires:

How to use the Polly.Caching.Distributed plugin

These notes assume you are familiar with using the .Net Standard IDistributedCache implementations. For information, see: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed . As described on that page, Microsoft provide a Redis implementation and an SQL server implementation for IDistributedCache.

Assuming you have an instance IDistributedCache distributedCache in hand (perhaps just configured and instantiated, perhaps provided to local code by Dependency Injection):

// Create a Polly cache policy for caching string results, using that IDistributedCache  instance.
var cachePolicy = Policy.Cache<string>(distributedCache.AsSyncCacheProvider<string>(), TimeSpan.FromMinutes(5));

// Create a Polly cache policy for caching byte[] results, using that IDistributedCache  instance.
var cachePolicy = Policy.Cache<byte[]>(distributedCache.AsSyncCacheProvider<byte[]>(), TimeSpan.FromMinutes(5));

// Or similarly for async executions returning string results:
var cachePolicy = Policy.CacheAsync<string>(distributedCache.AsAsyncCacheProvider<string>(), TimeSpan.FromMinutes(5));

// Or similarly for async executions returning  byte[] results:
var cachePolicy = Policy.CacheAsync<byte[]>(distributedCache.AsAsyncCacheProvider<byte[]>(), TimeSpan.FromMinutes(5));

// You can also use ASP.NET Core's DistributedCacheEntryOptions for specifying cache item time-to-live, as shown below. 
// All time-to-live functionality represented by DistributedCacheEntryOptions is supported.
DistributedCacheEntryOptions entryOptions = // ...
var cachePolicy = Policy.CacheAsync<byte[]>(distributedCache.AsAsyncCacheProvider<byte[]>(), entryOptions.AsTtlStrategy());
 

Configuration via DI in ASPNET Core:

// In this example we choose to pass a whole PolicyRegistry by dependency injection rather than the individual policy, on the assumption the webapp will probably use multiple policies across the app.

// For example: 
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDistributedRedisCache(options =>
        {
            options.Configuration = "localhost"; // or whatever
            options.InstanceName = "SampleInstance";
        });

        services.AddSingleton<Polly.Caching.IAsyncCacheProvider<string>>(serviceProvider => serviceProvider.GetRequiredService<IDistributedCache>().AsAsyncCacheProvider<string>());

        services.AddSingleton<Polly.Registry.IReadOnlyPolicyRegistry<string>, Polly.Registry.PolicyRegistry>((serviceProvider) =>
        {
            PolicyRegistry registry = new PolicyRegistry();
            registry.Add("myCachePolicy", Policy.CacheAsync<string>(serviceProvider.GetRequiredService<IAsyncCacheProvider<string>>(), TimeSpan.FromMinutes(5)));

            return registry;
            });

        // ...
    }
}

// In a controller, inject the policyRegistry and retrieve the policy:
// (magic string "myCachePolicy" hard-coded here only to keep the example simple) 
public MyController(IReadOnlyPolicyRegistry<string> policyRegistry)
{
    var _cachePolicy = policyRegistry.Get<IAsyncPolicy<string>>("myCachePolicy"); 
    // ...
}

Automatically serializing more complex type

The raw cache provider Polly.Caching.IDistributedCache allows you to cache items of type byte[] or string as those are the native formats supported by Microsoft.Extensions.Caching.Distributed.IDistributedCache. However, Polly also allows you to automatically serialize more complex types.

The package Polly.Caching.Serialization.Json (github; nuget) is a Polly ICacheItemSerializer<TResult, string> to serialize any type for use with Polly.Caching.IDistributedCache.

Configuration in .NET Core:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDistributedRedisCache(options =>
        {
            options.Configuration = "localhost"; // or whatever
            options.InstanceName = "SampleInstance";
        });

        // Obtain a Newtonsoft.Json.JsonSerializerSettings defining any settings to use for serialization
        // (could alternatively be obtained from a factory by DI)
        var serializerSettings = new JsonSerializerSettings()
        {
            // Any configuration options
        };

        // Register a Polly cache provider for caching ProductDetails entities, using the IDistributedCache instance and a Polly.Caching.Serialization.Json.JsonSerializer.
        // (ICacheItemSerializer<ProductDetails, string> could alternatively be obtained from a factory by DI)
        services.AddSingleton<Polly.Caching.IAsyncCacheProvider<ProductDetails>>(serviceProvider =>
            serviceProvider
                .GetRequiredService<IDistributedCache>()
                .AsAsyncCacheProvider<string>()
                .WithSerializer<ProductDetails, string>(
                    new Polly.Caching.Serialization.Json.JsonSerializer<ProductDetails>(serializerSettings)
                );

        // Register a Polly cache policy for caching ProductDetails entities, using that IDistributedCache instance.
        services.AddSingleton<Polly.Registry.IReadOnlyPolicyRegistry<string>, Polly.Registry.PolicyRegistry>((serviceProvider) =>
        {
            PolicyRegistry registry = new PolicyRegistry();
            registry.Add("productsCachePolicy", Policy.CacheAsync<ProductDetails>(serviceProvider.GetRequiredService<IAsyncCacheProvider<ProductDetails>>(), TimeSpan.FromMinutes(5)));

            return registry;
        });

        // ...
    }
}

// In a controller, inject the policyRegistry and retrieve the policy:
// (magic string "productsCachePolicy" hard-coded here only to keep the example simple) 
public MyController(IReadOnlyPolicyRegistry<string> policyRegistry)
{
    var _cachePolicy = policyRegistry.Get<IAsyncPolicy<ProductDetails>>("productsCachePolicy"); 
    // ...
}

Usage at the point of consumption

string productId = // ... from somewhere
string productDescription = await _cachePolicy.ExecuteAsync(context => getProductDescription(productId), 
    new Context(productId) // productId will also be the cache key used in this execution.
); 

For many more configuration options and usage examples of the main Polly CachePolicy, see the main Polly readme and deep doco on the Polly wiki. Additional overloads allow attaching delegates for cache errors, cache hits/misses etc, for logging and telemetry.

CachePolicy can of course also be combined with other policies in a PolicyWrap.

Release notes

For details of changes by release see the change log.

Acknowledgements

Instructions for Contributing

Please check out our Wiki for contributing guidelines. We are following the excellent GitHub Flow process, and would like to make sure you have all of the information needed to be a world-class contributor!

Since Polly is part of the .NET Foundation, we ask our contributors to abide by their Code of Conduct.

Also, we've stood up a Slack channel for easier real-time discussion of ideas and the general direction of Polly as a whole. Be sure to join the conversation today!

License

Licensed under the terms of the New BSD License

polly.caching.idistributedcache's People

Contributors

joelhulen avatar reisenberger avatar seanfarrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polly.caching.idistributedcache's Issues

Set package metadata

Summary

I wish for the nuget packages to have the licence expression property set correctly and the repository url

Details

The licence expression property should be set to the correct licence type I.e. Apache-2.0 as this will enable analysis of licences in use to occur in external tools & the license type will be shown in Nuget etc. By providing the repo url it will make it easier to contribute and can be used by source-link.

Add additional TFM to eliminate dependencies

Is your feature request related to a problem? Please describe.
I want to minimise dependencies in my project by utilising framework dependencies wherever possible

Describe the solution you'd like
I want the package to have an additional TFM added so that the explicit dependency on NetStandard.Library can be removed.

Describe alternatives you've considered
Accept the additional dependency

Additional context
n/a

NetStandardIDistributedCacheStringProvider breaks when using asp.net core 2.0

When using this package with asp.net core 2.0 I get the following exception when the cache value is set:

Method not found: 'System.Threading.Tasks.Task Microsoft.Extensions.Caching.Distributed.DistributedCacheExtensions.SetStringAsync(Microsoft.Extensions.Caching.Distributed.IDistributedCache, System.String, System.String, Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions)'.
   at Polly.Caching.IDistributedCache.NetStandardIDistributedCacheStringProvider.PutAsync(String key, String value, Ttl ttl, CancellationToken cancellationToken, Boolean continueOnCapturedContext)
   at Polly.Caching.CacheEngine.<ImplementationAsync>d__1`1.MoveNext() in C:\projects\polly\src\Polly.Shared\Caching\CacheEngineAsync.cs:line 58

Asp.net core 2 references Microsoft.Extensions.Caching.Abstractions version 2.0.1, which has changed the signature in DistributedCacheExtensions from:

public static Task SetStringAsync(this IDistributedCache cache, string key, string value);
public static Task SetStringAsync(this IDistributedCache cache, string key, string value, DistributedCacheEntryOptions options);

to

public static Task SetStringAsync(this IDistributedCache cache, string key, string value, DistributedCacheEntryOptions options = null);

This means that that the code is built against a method that no longer exists (specifically Task SetStringAsync(this IDistributedCache cache, string key, string value)) causing it to fail at runtime. It should be a simple matter of bumping the dependency version and releasing a new version of the package.

Remove explicit statement of NETStandard.Library 2.0 package dependency

Per https://github.com/dotnet/standard/blob/master/docs/faq.md#should-i-reference-the-meta-package-or-should-i-reference-individual-packages, it is not necessary (and in fact preferred not) to state a NETStandard.Library 2.0 package dependency, for a package targeting Net.Standard 2.0

Compare App-vNext/Polly.Caching.MemoryCache#26

Fixable for next release, by a commit similar to this: App-vNext/Polly.Caching.MemoryCache@6992214

NetStandardIDistributedCacheByteArrayProvider incorrectly passes CancellationToken

When using in .net core 3.1, the NetStandardIDistributedCacheByteArrayProvider does not pass CancellationToken received from Policy.

Please see this line:


image

When used in .net core 3.1, target framework is resolved to .net standard 2.1, thus we don't get CancellationToken passed and our code looks like this (decompiled via resharper):
image

Policy Execution that returns a strongly typed object

This is a question as I am sure I am missing something. I thought there was a way to execute a caching policy and have it return a strongly typed C# object instead of a string or byte[]. If not I am not sure I am following what the point of the serializer is or the ability to plug in a custom serializer.

I looked at the sample that gave the below code. The type has to be string or byte[] (as per the check in the code) or you get an error. However that means the Execute method always returns a string or a byte[] which means I am left to deserialize the string to an object via my code. If that is the case why have the TResult Deserialize(string objectToDeserialize) method on the ICacheItemSerializer<TResult, string> interface?

It seems I am missing something.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDistributedRedisCache(options =>
    {
        options.Configuration = "localhost"; // or whatever
        options.InstanceName = "SampleInstance";
    });

    services.AddSingleton<Polly.Caching.IAsyncCacheProvider<string>>(serviceProvider => serviceProvider.GetRequiredService<IDistributedCache>().AsAsyncCacheProvider<string>());

    services.AddSingleton<Polly.Registry.IReadOnlyPolicyRegistry<string>, Polly.Registry.PolicyRegistry>((serviceProvider) =>
    {
        PolicyRegistry registry = new PolicyRegistry();
        registry.Add("myCachePolicy", Policy.CacheAsync<string>(serviceProvider.GetRequiredService<IAsyncCacheProvider<string>>(), TimeSpan.FromMinutes(5)));

        return registry;
        });

    // ...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.