I have a pretty slow controller action, which does some raporting here and there. I only need to refresh the data every few days, so it was no brainer to static cache the result.
The problem is, that the action takes solid few minutes to complete and I am not sure whats the most optimal way to expire the old data and replace them with the new ones.
Now the problem with just generic expire/request is that for few minutes (time when the action is running) those data are unavailable.
Is there any resonable way to overcome this gap using just static cache mechanisms in Rails? Or should I just rebuild the whole thing in a different way?
Rails has a built-in way to use stale caches for just a bit longer when it expires while the new cache value is being regenerated. It’s the
:race_condition_ttlsetting used in conjuction with:expires_in, as describe in the Rails Guides on Caching.With Rails Fragment caching the syntax should be:
Results:
race_condition_ttlwas introduced to prevent multiple processes from regenerating a cache simultaneuosly, which would result in all processes reading the data from the db at once etc. on a highly requested resource, but I think it should work well for your situation.How to choose the timing for
:expires_inand:race_condition_ttlis your choice then, I’d suggest calculating it like this:expires_in + race_condition = expires_in_that_you_would_usually_set. This way the cache is regenerated more often but also fresher, especially if the action/view is not rendered that often.