-
Notifications
You must be signed in to change notification settings - Fork 171
Description
Problem
When we do a GetOrSet we can access a factory context, like this:
var cacheKey = "foo";
cache.GetOrSet<string>(
cacheKey,
(ctx, ct) => {
// WE CAN WORK WITH ctx HERE
}
);All is good, but if we also need to access the cache key inside of the factory itself, the way to do it is by referencing that inside of the lambda, like this:
var cacheKey = "foo";
cache.GetOrSet<string>(
cacheKey,
(ctx, ct) => {
var tmp = cacheKey; // HERE WE CAN REFERENCE cacheKey
}
);This works, but it also inadvertently creates a closure to capture the cacheKey variable from outside: this in turn allocates more memory, and prevent us from being able to use a static lambda, which can be an effective optimization technique.
Also, when using FusionCache we can specify a CacheKeyPrefix (typically used along with Named Caches) and in that case the cache key used internally would be processed: for example if we specify a CacheKeyPrefix as "MyPrefix:" and call GetOrSet("foo", ...), the cache key used internally would be processed and become "MyPrefix:foo".
Therefore we should be able to access both, the processed key and the original key.
Finally, this need has been recently reported in a couple of issues (see here and here).
Solution
I'm adding 2 new properties to the factory context (of type FusionCacheFactoryExecutionContext<TValue>):
string Key { get; }string OriginalKey { get; }
both, as can be seen, read only.
If this way we'll be able to do this:
var cacheKey = "foo";
cache.GetOrSet<string>(
cacheKey,
(ctx, ct) => {
var tmp1 = ctx.Key; // HERE WE CAN REFERENCE THE (PROCESSED) CACHE KEY
var tmp2 = ctx.OriginalKey; // HERE WE CAN REFERENCE THE (ORIGINAL) CACHE KEY
}
);In this way a closure will not be created, and the lambda itself (the factory) may even be marked as static.
Note
Of course if CacheKeyPrefix is not being used, both properties will have the same value.
Naming
Regarding the names of the 2 new properties ("Key" and "OriginalKey"), someone may be thinking: why not call the 2 properties ProcessedKey and OriginalKey? In particular, why use "Key" and not "ProcessedKey"?
That was the first thing I thought too but then I remembered that the simple term "key", used to refer to the processed one, is already being used inside FusionCache in multiple places, like:
Therefore, we can say, the simple term "key" has always meant the processed one, therefore using in only this case the term "ProcessedKey" would be non uniform with the rest.
To be on the safe side I also added some xml comments to make this as evident as possible, like this:
On top of this, when someone will type ctx. and then "key", they'll see this:
showing both and sparking the question, even for people not knowing the 2 already.
This, ideally, should do the trick.

