Skip to content

[API Proposal]: HybridCache - should a HC-backed IDistributedCache be offered? #5539

Open
@mgravell

Description

Background and motivation

Currently, HybridCache optionally consumes IDistributedCache (and IBufferDistributedCache via type-testing) as the L2 backend, typically for out-of-process/off-box storage (Redis etc).

A lot of existing code consumes IDistributedCache, and while in a perfect world they would migrate to HybridCache, we do not live in a perfect world, so there is a question as to whether it may be useful to optionally offer an IDistributedCache that is, effectively, a L1+L2 wrapper.

Considerations

  • this option is only relevant when using L1+L2 (i.e. a non-trivial IDistributedCache backend); if you only want L1, there is already AddDistributedMemoryCache which does exactly that
  • this would require careful configuration, to disambiguate the optional out-of-proc IDistributedCache backend from the exposed backend - this could be either via keyed-DI, or via explicit configuration against the HybridCacheOptions
  • the API would be different and would not have full feature parity, since IDistributedCache has separate get/put APIs - this is manageable, however
  • for correctness guarantees, we would need to perform defensive byte[] copies when using IDistributedCache, but that doesn't present a significant change - that is already expected
  • if done, it is easy to also support IBufferDistributedCache (and we should do so), although should not expect massive usage; the entire point of things like HybridCache is to make that a non-concern for application code

Usage example

(entirely speculative and open to discussion)

// existing L2 registraction
services.AddStackExchangeRedisCache(...); // some L2

//  existing service usage
public SomeService(IDistributedCache cache)
{
    public async Task SomeMethodAsync()
    {
        // blah, cache.GetAsync etc
    }
}

// new registration
services.AddHybridCache(...).WithKeyedDistributedCache("some key");

with the change to existing usage consisting of:

- public SomeService(IDistributedCache cache)
+ public SomeService([FromKeyedServices("some key")] IDistributedCache cache)

The downside of this is that it still requires per-usage changes, but that may be desirable anyway, to ensure the usage is fully considered.

Questions

  • is this whole thing needed?
  • is there a better way of handling the two separate IDistributedCache uses, that works better?
  • should the key be defaulted to something like typeof(HybridCache) if not specified, or is that silly?

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions