Closed xPaw closed 1 year ago
Hello and thank you for the interest in the library!
When prototyping API surface, I ended up deciding against such method because it looked quite cumbersome to call e.g. Cached<UserData>.Save(id, tenant, userData, TimeSpan.FromMinutes(3));
vs userData.Cache(id, tenant, TimeSpan.FromMinutes(3));
.
In addition, due to the interaction between the static cache nature of the library and C# overload resolution, placing method arguments Kn and V adjacent to each other increased the likelihood of user error.
Could you provide a more specific example of your preferred usage? I'll consider supporting that scenario. For cache seeding with multiple values, you can employ CachedRange<V>.Save
, which offers better performance.
P.S.: In retrospect, I believe that implementing this as a static cache may not have been the best decision, despite its appeal for minimal API prototypes / fine-grained microservices. Although it has benefits for code generation, they do not sufficiently offset the disadvantages.
My particular use case was caching strings in a received event, and retrieve it from the cache in a separate event. So in this instance, always writing new key/values to the cache.
I think as an alternative option we can do the following API that would allow composing limits and multi-argument keys without making it too cumbersome:
namespace FastCache;
public static partial class Cached<V>
{
public static Cached<K, V> FromKey<K>(K key) { }
...
public static Cached<(K1, K2, K3), V> FromKey(K1 param1, K2 param2, K3 param3) { }
...
}
e.g.
Cached<EventPayload>
.FromKey(eventId, queueId)
.Save(payload, TimeSpan.FromSeconds(300));
Important: this is static cache so Cached<string>
will behave like a global interning pool (except likely better performance, I haven't touched the actual interning pool since .NET framework days). If you are okay with this - good, if not - feel free to use something like readonly record struct EventString(string Value);
to ensure isolation.
Do I understand you correctly that it would be similar to TryGet?
Cached<SalesReport>.FromKey(companyId).Save(report, TimeSpan.FromMinutes(60));
if we use the sample from the readme.
I think it might be more confusing because it won't fetch the cached value if there is one.
Hmm, I agree, and so does GPT-4, seems there aren't that many ways to make it more idiomatic. I will add Cached<V>.Save(K1...K7 key, V Value, TimeSpan expiration)
+ limit overloads, it is consistent with CachedRange<V>
which helps. At least there won't be any performance difference between now three ways of doing it which other libraries seem to suffer from.
It seems that the only way to save without getting from cache first is to use
FastCache.Extensions
. I prefer using explicit methods rather than extension for something like this.