Add `Cached<T>.Save` overload
xPaw opened this issue · 6 comments
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.
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.