Skip to content

Commit e5d3d78

Browse files
authored
Merge pull request rails#50071 from tgwizard/fix-cache-fetch-multi-read-write-order-of-operations
Adjust instr. for Cache::Store#fetch_multi so writes are after reads
2 parents b7d9654 + 2251a4b commit e5d3d78

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

activesupport/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Make the order of read_multi and write_multi notifications for `Cache::Store#fetch_multi` operations match the order they are executed in.
2+
3+
*Adam Renberg Tamm*
4+
15
* Make return values of `Cache::Store#write` consistent.
26

37
The return value was not specified before. Now it returns `true` on a successful write,

activesupport/lib/active_support/cache.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,14 @@ def fetch_multi(*names)
605605
options = names.extract_options!
606606
options = merged_options(options)
607607

608-
instrument_multi :read_multi, names, options do |payload|
608+
writes = {}
609+
ordered = instrument_multi :read_multi, names, options do |payload|
609610
if options[:force]
610611
reads = {}
611612
else
612613
reads = read_multi_entries(names, **options)
613614
end
614615

615-
writes = {}
616616
ordered = names.index_with do |name|
617617
reads.fetch(name) { writes[name] = yield(name) }
618618
end
@@ -621,10 +621,12 @@ def fetch_multi(*names)
621621
payload[:hits] = reads.keys
622622
payload[:super_operation] = :fetch_multi
623623

624-
write_multi(writes, options)
625-
626624
ordered
627625
end
626+
627+
write_multi(writes, options)
628+
629+
ordered
628630
end
629631

630632
# Writes the value to the cache with the key. The value must be supported

activesupport/test/cache/behaviors/cache_instrumentation_behavior.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ def test_instrumentation_with_fetch_multi_as_super_operation
3434
assert_equal @cache.class.name, events[0].payload[:store]
3535
end
3636

37+
def test_fetch_multi_instrumentation_order_of_operations
38+
operations = []
39+
callback = ->(name, *) { operations << name }
40+
41+
key_1 = SecureRandom.uuid
42+
key_2 = SecureRandom.uuid
43+
44+
ActiveSupport::Notifications.subscribed(callback, /^cache_(read_multi|write_multi)\.active_support$/) do
45+
@cache.fetch_multi(key_1, key_2) { |key| key * 2 }
46+
end
47+
48+
assert_equal %w[ cache_read_multi.active_support cache_write_multi.active_support ], operations
49+
end
50+
3751
def test_read_multi_instrumentation
3852
key_1 = SecureRandom.uuid
3953
@cache.write(key_1, SecureRandom.alphanumeric)

0 commit comments

Comments
 (0)