As you probably know, the builtin memcached store wraps values in instances of ActiveSupport::Cache::Entry. I am studying whether we could get rid of it and your input would be valuable in helping us take a decision.
In addition to the cached value, these entries store the creation timestamp, TTL, and compression flag.
Rails 4 uses Dalli for the builtin memcached cache store, and Dalli supports compression. It uses a flag to mark the stored value. We do not need to handle compression by hand in AS with Dalli.
The creation and TTL values are there because albeit memcached handles expiration, Active Support is doing a first expiration pass on the values: on writing (in 3-2-stable, but should be also on master) Active Support adds 5 minutes to the TTL set by the user. Then when an entry is read, there is code common to all stores that checks whether the entry expired, and if so deletes manually the entry.
If you read the entry in that 5 minute window, expiration is handled by AS, otherwise, it is handled by memcached (5 minutes later than the user specified).
That manual management of expiration makes sense if the store does not support expiration (like the file store). What’s the point in the memcached store? We need to support :race_condition_ttl.
:race_condition_ttl is an optional TTL you may pass in a fetch call that goes like this:
-
If we read the entry and according to the user it has expired, then reset the TTL to race_condition_ttl to have everyone else fetch the “stale” entry while this process computes the new fresh value.
-
When the value is computed, store it with the normal TTL (+ 5 minutes), and return it.
This feature was introduced as a way to avoid the dog pile effect in heavy loaded websites that result from too many processes trying to get the fresh value when said value is expensive to compute. This can indeed be a problem.
Memcached does not give you the TTL of a key, therefore we need this timestamp to support this feature.
Question is, how many people need this? I wonder if the trade-off justifies taxing all users. There are suboptimal techniques that may help sites up to certain sizes that involve a second key that acts as an advisory lock or something like that. And this complete solution could be a cache store implemented by someone else in a separate plugin, if you totally need this :race_condition_ttl.
So, the question is, do you guys use this option? Thoughts?