Skip to content

Commit 5d4057b

Browse files
authored
Merge pull request rails#54855 from ghiculescu/read_counter
Add `Cache#read_counter` and `Cache#write_counter`
2 parents b132744 + a7dcbde commit 5d4057b

File tree

5 files changed

+69
-0
lines changed

5 files changed

+69
-0
lines changed

activesupport/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
* Add `Cache#read_counter` and `Cache#write_counter`
2+
3+
```ruby
4+
Rails.cache.write_counter("foo", 1)
5+
Rails.cache.read_counter("foo") # => 1
6+
Rails.cache.increment("foo")
7+
Rails.cache.read_counter("foo") # => 2
8+
```
9+
10+
*Alex Ghiculescu*
11+
112
* Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports
213

314
Captures all reported errors from within the block that match the given

activesupport/lib/active_support/cache.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,32 @@ def decrement(name, amount = 1, options = nil)
743743
raise NotImplementedError.new("#{self.class.name} does not support decrement")
744744
end
745745

746+
# Reads a counter that was set by #increment / #decrement.
747+
#
748+
# cache.write_counter("foo", 1)
749+
# cache.read_counter("foo") # => 1
750+
# cache.increment("foo")
751+
# cache.read_counter("foo") # => 2
752+
#
753+
# Options are passed to the underlying cache implementation.
754+
def read_counter(name, **options)
755+
options = merged_options(options).merge(raw: true)
756+
read(name, **options)&.to_i
757+
end
758+
759+
# Writes a counter that can then be modified by #increment / #decrement.
760+
#
761+
# cache.write_counter("foo", 1)
762+
# cache.read_counter("foo") # => 1
763+
# cache.increment("foo")
764+
# cache.read_counter("foo") # => 2
765+
#
766+
# Options are passed to the underlying cache implementation.
767+
def write_counter(name, value, **options)
768+
options = merged_options(options).merge(raw: true)
769+
write(name, value.to_i, **options)
770+
end
771+
746772
# Cleans up the cache by removing expired entries.
747773
#
748774
# Options are passed to the underlying cache implementation.

activesupport/lib/active_support/cache/mem_cache_store.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ def inspect
126126
#
127127
# Incrementing a non-numeric value, or a value written without
128128
# <tt>raw: true</tt>, will fail and return +nil+.
129+
#
130+
# To read the value later, call #read_counter:
131+
#
132+
# cache.increment("baz") # => 7
133+
# cache.read_counter("baz") # 7
129134
def increment(name, amount = 1, options = nil)
130135
options = merged_options(options)
131136
key = normalize_key(name, options)
@@ -152,6 +157,11 @@ def increment(name, amount = 1, options = nil)
152157
#
153158
# Decrementing a non-numeric value, or a value written without
154159
# <tt>raw: true</tt>, will fail and return +nil+.
160+
#
161+
# To read the value later, call #read_counter:
162+
#
163+
# cache.decrement("baz") # => 3
164+
# cache.read_counter("baz") # 3
155165
def decrement(name, amount = 1, options = nil)
156166
options = merged_options(options)
157167
key = normalize_key(name, options)

activesupport/lib/active_support/cache/redis_cache_store.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ def delete_matched(matcher, options = nil)
250250
# Incrementing a non-numeric value, or a value written without
251251
# <tt>raw: true</tt>, will fail and return +nil+.
252252
#
253+
# To read the value later, call #read_counter:
254+
#
255+
# cache.increment("baz") # => 7
256+
# cache.read_counter("baz") # 7
257+
#
253258
# Failsafe: Raises errors.
254259
def increment(name, amount = 1, options = nil)
255260
options = merged_options(options)
@@ -277,6 +282,11 @@ def increment(name, amount = 1, options = nil)
277282
# Decrementing a non-numeric value, or a value written without
278283
# <tt>raw: true</tt>, will fail and return +nil+.
279284
#
285+
# To read the value later, call #read_counter:
286+
#
287+
# cache.decrement("baz") # => 3
288+
# cache.read_counter("baz") # 3
289+
#
280290
# Failsafe: Raises errors.
281291
def decrement(name, amount = 1, options = nil)
282292
options = merged_options(options)

activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ def test_decrement
3131
assert_equal @cache.is_a?(ActiveSupport::Cache::MemCacheStore) ? 0 : -100, missing
3232
end
3333

34+
def test_read_counter_and_write_counter
35+
key = SecureRandom.uuid
36+
@cache.write_counter(key, 1)
37+
assert_equal 1, @cache.read(key, raw: true).to_i
38+
39+
assert_equal 1, @cache.read_counter(key)
40+
assert_equal 2, @cache.increment(key)
41+
assert_equal 2, @cache.read_counter(key)
42+
43+
assert_nil @cache.read_counter(SecureRandom.alphanumeric)
44+
end
45+
3446
def test_ttl_isnt_updated
3547
key = SecureRandom.uuid
3648

0 commit comments

Comments
 (0)