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
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:
1) 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.
2) 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
So, the question is, do you guys use this option? Thoughts?