1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #30268 from ignatiusreza/instrumentation

add instrumentation for read_multi
This commit is contained in:
Ryuta Kamizono 2018-01-11 09:14:56 +09:00
commit 2a934aa3c9
4 changed files with 64 additions and 49 deletions

View file

@ -1,3 +1,7 @@
* Add missing instrumentation for `read_multi` in `ActiveSupport::Cache::Store`.
*Ignatius Reza Lesmana*
* `assert_changes` will always assert that the expression changes, * `assert_changes` will always assert that the expression changes,
regardless of `from:` and `to:` argument combinations. regardless of `from:` and `to:` argument combinations.

View file

@ -357,23 +357,11 @@ module ActiveSupport
options = names.extract_options! options = names.extract_options!
options = merged_options(options) options = merged_options(options)
results = {} instrument :read_multi, names, options do |payload|
names.each do |name| read_multi_entries(names, options).tap do |results|
key = normalize_key(name, options) payload[:hits] = results.keys
version = normalize_version(name, options)
entry = read_entry(key, options)
if entry
if entry.expired?
delete_entry(key, options)
elsif entry.mismatched?(version)
# Skip mismatched versions
else
results[name] = entry.value
end
end end
end end
results
end end
# Cache Storage API to write multiple values at once. # Cache Storage API to write multiple values at once.
@ -414,14 +402,19 @@ module ActiveSupport
options = names.extract_options! options = names.extract_options!
options = merged_options(options) options = merged_options(options)
read_multi(*names, options).tap do |results| instrument :read_multi, names, options do |payload|
writes = {} read_multi_entries(names, options).tap do |results|
payload[:hits] = results.keys
payload[:super_operation] = :fetch_multi
(names - results.keys).each do |name| writes = {}
results[name] = writes[name] = yield(name)
(names - results.keys).each do |name|
results[name] = writes[name] = yield(name)
end
write_multi writes, options
end end
write_multi writes, options
end end
end end
@ -538,6 +531,28 @@ module ActiveSupport
raise NotImplementedError.new raise NotImplementedError.new
end end
# Reads multiple entries from the cache implementation. Subclasses MAY
# implement this method.
def read_multi_entries(names, options)
results = {}
names.each do |name|
key = normalize_key(name, options)
version = normalize_version(name, options)
entry = read_entry(key, options)
if entry
if entry.expired?
delete_entry(key, options)
elsif entry.mismatched?(version)
# Skip mismatched versions
else
results[name] = entry.value
end
end
end
results
end
# Writes multiple entries to the cache implementation. Subclasses MAY # Writes multiple entries to the cache implementation. Subclasses MAY
# implement this method. # implement this method.
def write_multi_entries(hash, options) def write_multi_entries(hash, options)

View file

@ -91,28 +91,6 @@ module ActiveSupport
end end
end end
# Reads multiple values from the cache using a single call to the
# servers for all keys. Options can be passed in the last argument.
def read_multi(*names)
options = names.extract_options!
options = merged_options(options)
keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
raw_values = @data.get_multi(keys_to_names.keys)
values = {}
raw_values.each do |key, value|
entry = deserialize_entry(value)
unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
values[keys_to_names[key]] = entry.value
end
end
values
end
# Increment a cached value. This method uses the memcached incr atomic # Increment a cached value. This method uses the memcached incr atomic
# operator and can only be used on values written with the :raw option. # operator and can only be used on values written with the :raw option.
# Calling it on a value not stored with :raw will initialize that value # Calling it on a value not stored with :raw will initialize that value
@ -170,6 +148,24 @@ module ActiveSupport
end end
end end
# Reads multiple entries from the cache implementation.
def read_multi_entries(names, options)
keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
raw_values = @data.get_multi(keys_to_names.keys)
values = {}
raw_values.each do |key, value|
entry = deserialize_entry(value)
unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
values[keys_to_names[key]] = entry.value
end
end
values
end
# Delete an entry from the cache. # Delete an entry from the cache.
def delete_entry(key, options) def delete_entry(key, options)
rescue_error_with(false) { @data.delete(key) } rescue_error_with(false) { @data.delete(key) }

View file

@ -19,7 +19,7 @@ end
class CacheStoreWriteMultiInstrumentationTest < ActiveSupport::TestCase class CacheStoreWriteMultiInstrumentationTest < ActiveSupport::TestCase
setup do setup do
@cache = ActiveSupport::Cache.lookup_store(:null_store) @cache = ActiveSupport::Cache.lookup_store(:memory_store)
end end
test "instrumentation" do test "instrumentation" do
@ -35,15 +35,15 @@ class CacheStoreWriteMultiInstrumentationTest < ActiveSupport::TestCase
end end
test "instrumentation with fetch_multi as super operation" do test "instrumentation with fetch_multi as super operation" do
skip "fetch_multi isn't instrumented yet" @cache.write("b", "bb")
events = with_instrumentation "write_multi" do events = with_instrumentation "read_multi" do
@cache.fetch_multi("a", "b") { |key| key * 2 } @cache.fetch_multi("a", "b") { |key| key * 2 }
end end
assert_equal %w[ cache_write_multi.active_support ], events.map(&:name) assert_equal %w[ cache_read_multi.active_support ], events.map(&:name)
assert_nil events[0].payload[:super_operation] assert_equal :fetch_multi, events[0].payload[:super_operation]
assert !events[0].payload[:hit] assert_equal ["b"], events[0].payload[:hits]
end end
private private