November 25, 2020 by Marco Cecconi
It is with great pleasure that we are announcing today our newest open source project intelligent cache. We are very enthusiastic about this project because we think we constructed a very usable interface and ecosystem which you can rely on and extend extremely easily. Let me talk to you about it.
Intelligent Cache is currently a dotnet-core, netstandard and .net 4.6.1 library but it's easily extensible to almost any other language.
Fork it here -- Nuget Package here
At the heart of the library, there is a pattern (actually a monad) that defines two important things:
The cache interface at the moment is very minimalistic, as we try to include only what we actually need in production and not to add features based on perceived, but not actual, needs.
public interface ICache
{
Task<T> GetSetAsync<T>(string key, Func<CancellationToken, Task<T>> calculateValue, TimeSpan duration, CancellationToken cancellationToken = default) where T: class;
T GetSet<T>(string key, Func<T> calculateValue, TimeSpan duration) where T: class;
Task InvalidateAsync(string key, CancellationToken cancellationToken = default);
void Invalidate(string key);
}
There are both async and sync versions of the cache to support both future and current systems that might not have adopted async or that will adopt it in the future. The two main methods are GetSet
and Invalidate
. The first returns an object from the cache and fills the cache using the given lambda if the key specified is empty or null. The second method, Invalidate
, clears the current key and it's useful in case we know that the current cache has become stale, typically in case of updates.
The composition function chains together different caches so they "fall through": if the requested key is not present in the first cache, it looks in the second before actually fetching a new value. This is useful to create distributed caches, but also to add other kinds of behaviors as we will see below. The composition class has this signature.
public class CompositeCache : ICache
{
public CompositeCache(ICache level1, ICache level2)
{
// ...
}
// ICache implementation ...
}
At the moment we have 3 implementations of the cache, a local cache based on MemoryCache
, a distributed cache based on Redis, and a passthrough cache. On top of these three basic building blocks, we have two classes that should be used together to distribute invalidation messages in case you need to keep caches in sync over multiple servers.
Here is what the dataflow of a full-fledged 2 tier distributed library looks like:
This cache can be built with the following composition pattern.
ISubscriber subscriber = GetRedisSubscriber();
var invalidationChannel = "cache-invalidations";
var cache = new CompositeCache(
new RedisInvalidationReceiver(
new MemoryCache(/* arguments */),
subscriber,
invalidationChannel
),
new CompositeCache(
new RedisCache(/* arguments */),
new RedisInvalidationSender(subscriber, invalidationChannel)
)
);
Of course, there's much more information including working examples and tests on the intelligent cache repo.
The caching library is built to be trivial to extend with your own implementation. Let's say that you wanted to log to console all operations of a cache. This can be done very easily by extending ICache and composing:
public class LogToConsoleBehavior: ICache
{
public T GetSet<T>(string key, Func<T> calculateValue, TimeSpan duration) where T: class
{
Console.WriteLine("GetSet called");
return calculateValue();
}
// other methods are implemented similarly
}
ICache cache = new Cache(); // this is the cache we want to extend with logging
var logToConsoleCache = new CompositeCache(new LogToConsoleBehavior(), cache);
// now logToConsoleCache is just like cache, except it logs to console
We are looking for contributors, please look at our open issues if you are looking for something to do. If you find this project useful, please give us a star on GitHub and share the library.
The project has been developed through the sponsorship of Intelligent Hack and iSolutions. Please give them a shout out if you can.
Hi, I'm Marco Cecconi. I am the founder of Intelligent Hack, developer, hacker, blogger, conference lecturer. Bio: ex Stack Overflow core team, ex Toptal EM.
Read moreMarch 12, 2023 by Marco Cecconi
Stack Overflow could benefit from adopting a using conversational AI to provide specific answers
Read moreOctober 15, 2021 by Marco Cecconi
Multiple people with my name use my email address and I can read their email, chaos ensues!
Read moreSeptember 29, 2021 by Marco Cecconi
After years of building, our top-notch consultancy to help start-ups and scale-ups create great, scalable products, I think it is high time I added an update to how it is going and what's next for us.
Read moreFebruary 03, 2021 by Marco Cecconi
A lesson in building communities by Stack Overflow's most prominent community manager emeritus, Shog9
Read moreDecember 02, 2020 by Marco Cecconi
Some lessons learned over the past 8 years of remote work in some of the best remote companies on the planet
Read moreWe can say that Mr. Robot is having a moment. The main character was one of the top choices and thus is perhaps the most/least realistic/annoying/inspiring portrayal of what it’s like to be a computer programmer today.
Read more…