Cache package that sits in front of a slow MFA?

I have a pretty simple need – simple enough that it’s not a big deal to implement it as a GenServer or similar, but it’s a common enough use case that someone else must have come up with something that fits the bill. The basic need is to have a cache sit in front of a slow MFA call, e.g. a database query. So the cache acts as the source-of-truth, and the MFA call gets applied periodically so it stays “reasonably” up-to-date, and I can hit the database once every few minutes instead of once every few milliseconds and all would be well with the world.

I’m imagining a GenServer that could be started up something like:

GenCache.start_link(%{name: :db_query1, module: MyApp, function: :slow_db_query1, args: [], refresh_interval_ms: 300_000})

which would call MyApp.slow_db_query1/0 every 5 minutes and cache the result in the GenServer state. I could access the cached data via something like:

GenCache.get(:db_query1)

or force it to refresh via

GenCache.refresh(:db_query1)

and a few other functions – hopefully this expresses the idea.

Is anyone aware of such a package that could be pointed at arbitrary existing functions? I’m not sure if this simple use case would even justify a stand-alone package, but I thought the community would have some valuable thoughts on it. Thanks in advance!

1 Like

Cachex for example will fit the bill.

3 Likes

I’ve used Cachex, but it might be overkill in this case… I think I’d need to write an interface to prep it that would be as least as complicated as the GenServer that’s in my mind to do the auto-refreshing caching. Maybe it’s changed since I last used it though… I’ll take a look.

There is a bit of boilerplate but not too much, and then you just have to provide the fallback callback in case of cache miss.

Now this strategy works well but it is different than using whatever is in the cache, and imperatively update the cache regularly.