sonic-pi
https://github.com/sonic-pi-net/sonic-pi
C++
Code. Music. Live.
ActiveSupport::Cache::Store#fetch
Fetches data from the cache, using the given key. If there is data in
the cache with the given key, then that data is returned.
If there is no such data in the cache (a cache miss), then +nil+ will be
returned. However, if a block has been passed, that block will be passed
the key and executed in the event of a cache miss. The return value of the
block will be written to the cache under the given cache key, and that
return value will be returned.
cache.write('today', 'Monday')
cache.fetch('today') # => "Monday"
cache.fetch('city') # => nil
cache.fetch('city') do
'Duckburgh'
end
cache.fetch('city') # => "Duckburgh"
You may also specify additional options via the +options+ argument.
Setting <tt>force: true</tt> will force a cache miss:
cache.write('today', 'Monday')
cache.fetch('today', force: true) # => nil
Setting <tt>:compress</tt> will store a large cache entry set by the call
in a compressed format.
Setting <tt>:expires_in</tt> will set an expiration time on the cache.
All caches support auto-expiring content after a specified number of
seconds. This value can be specified as an option to the constructor
(in which case all entries will be affected), or it can be supplied to
the +fetch+ or +write+ method to effect just one entry.
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
Setting <tt>:race_condition_ttl</tt> is very useful in situations where
a cache entry is used very frequently and is under heavy load. If a
cache expires and due to heavy load several different processes will try
to read data natively and then they all will try to write to cache. To
avoid that case the first process to find an expired cache entry will
bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>.
Yes, this process is extending the time for a stale value by another few
seconds. Because of extended life of the previous cache, other processes
will continue to use slightly stale data for a just a bit longer. In the
meantime that first process will go ahead and will write into cache the
new value. After that all the processes will start getting new value.
The key is to keep <tt>:race_condition_ttl</tt> small.
If the process regenerating the entry errors out, the entry will be
regenerated after the specified number of seconds. Also note that the
life of stale cache is extended only if it expired recently. Otherwise
a new value is generated and <tt>:race_condition_ttl</tt> does not play
any role.
# Set all values to expire after one minute.
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
cache.write('foo', 'original value')
val_1 = nil
val_2 = nil
sleep 60
Thread.new do
val_1 = cache.fetch('foo', race_condition_ttl: 10) do
sleep 1
'new value 1'
end
end
Thread.new do
val_2 = cache.fetch('foo', race_condition_ttl: 10) do
'new value 2'
end
end
# val_1 => "new value 1"
# val_2 => "original value"
# sleep 10 # First thread extend the life of cache by another 10 seconds
# cache.fetch('foo') => "new value 1"
Other options will be handled by the specific cache store implementation.
Internally, #fetch calls #read_entry, and calls #write_entry on a cache
miss. +options+ will be passed to the #read and #write calls.
For example, MemCacheStore's #write method supports the +:raw+
option, which tells the memcached server to store all values as strings.
We can use this option with #fetch too:
cache = ActiveSupport::Cache::MemCacheStore.new
cache.fetch("foo", force: true, raw: true) do
:bar
end
cache.fetch('foo') # => "bar"Edit
git clone [email protected]:sonic-pi-net/sonic-pi.git
cd sonic-pi
open app/server/ruby/vendor/activesupport-7.0.6/lib/active_support/cache.rb
Contribute
# Make a new branchgit checkout -b -your-name--update-docs-ActiveSupport--Cache--Store-fetch-for-pr
# Commit to gitgit add app/server/ruby/vendor/activesupport-7.0.6/lib/active_support/cache.rbgit commit -m "better docs for ActiveSupport::Cache::Store#fetch"
# Open pull requestgem install hub # on a mac you can `brew install hub`
hub fork
git push <your name> -your-name--update-docs-ActiveSupport--Cache--Store-fetch-for-pr
hub pull-request
# Celebrate!