Allow fetching multiple values from the cache at once
Add a simple API for fetching a list of entries from the cache, where any missing entries are computed by a supplied block.
This commit is contained in:
parent
6023a50491
commit
36d41a15c3
@ -1,3 +1,15 @@
|
||||
* No changes.
|
||||
* Add a `fetch_multi` method to the cache stores. The method provides
|
||||
an easy to use API for fetching multiple values from the cache.
|
||||
|
||||
Example:
|
||||
|
||||
# Calculating scores is expensive, so we only do it for posts
|
||||
# that have been updated. Cache keys are automatically extracted
|
||||
# from objects that define a #cache_key method.
|
||||
scores = Rails.cache.fetch_multi(*posts) do |post|
|
||||
calculate_score(post)
|
||||
end
|
||||
|
||||
*Daniel Schierbeck*
|
||||
|
||||
Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/activesupport/CHANGELOG.md) for previous changes.
|
||||
|
@ -352,6 +352,34 @@ def read_multi(*names)
|
||||
results
|
||||
end
|
||||
|
||||
# Fetches data from the cache, using the given keys. If there is data in
|
||||
# the cache with the given keys, then that data is returned. Otherwise,
|
||||
# the supplied block is called for each key for which there was no data,
|
||||
# and the result will be written to the cache and returned.
|
||||
#
|
||||
# Options are passed to the underlying cache implementation.
|
||||
#
|
||||
# Returns an array with the data for each of the names. For example:
|
||||
#
|
||||
# cache.write("bim", "bam")
|
||||
# cache.fetch_multi("bim", "boom") {|key| key * 2 }
|
||||
# #=> ["bam", "boomboom"]
|
||||
#
|
||||
def fetch_multi(*names)
|
||||
options = names.extract_options!
|
||||
options = merged_options(options)
|
||||
|
||||
results = read_multi(*names, options)
|
||||
|
||||
names.map do |name|
|
||||
results.fetch(name) do
|
||||
value = yield name
|
||||
write(name, value, options)
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Writes the value to the cache, with the key.
|
||||
#
|
||||
# Options are passed to the underlying cache implementation.
|
||||
|
@ -257,6 +257,26 @@ def test_read_multi_with_expires
|
||||
assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
||||
end
|
||||
|
||||
def test_fetch_multi
|
||||
@cache.write('foo', 'bar')
|
||||
@cache.write('fud', 'biz')
|
||||
|
||||
values = @cache.fetch_multi('foo', 'fu', 'fud') {|value| value * 2 }
|
||||
|
||||
assert_equal(["bar", "fufu", "biz"], values)
|
||||
assert_equal("fufu", @cache.read('fu'))
|
||||
end
|
||||
|
||||
def test_multi_with_objects
|
||||
foo = stub(:title => "FOO!", :cache_key => "foo")
|
||||
bar = stub(:cache_key => "bar")
|
||||
|
||||
@cache.write('bar', "BAM!")
|
||||
|
||||
values = @cache.fetch_multi(foo, bar) {|object| object.title }
|
||||
assert_equal(["FOO!", "BAM!"], values)
|
||||
end
|
||||
|
||||
def test_read_and_write_compressed_small_data
|
||||
@cache.write('foo', 'bar', :compress => true)
|
||||
assert_equal 'bar', @cache.read('foo')
|
||||
|
Loading…
Reference in New Issue
Block a user