Skip to content

Commit cd4708b

Browse files
authored
Merge pull request rails#54460 from ryush00/cache-pool-timeout-and-tests
Handle ConnectionPool::TimeoutError in Redis and Memcached stores
2 parents 2e34511 + 3383ca1 commit cd4708b

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

activesupport/lib/active_support/cache/mem_cache_store.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def deserialize_entry(payload, raw: false, **)
273273

274274
def rescue_error_with(fallback)
275275
yield
276-
rescue Dalli::DalliError, ConnectionPool::Error => error
276+
rescue Dalli::DalliError, ConnectionPool::Error, ConnectionPool::TimeoutError => error
277277
logger.error("DalliError (#{error}): #{error.message}") if logger
278278
ActiveSupport.error_reporter&.report(
279279
error,

activesupport/lib/active_support/cache/redis_cache_store.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ def supports_expire_nx?
497497

498498
def failsafe(method, returning: nil)
499499
yield
500-
rescue ::Redis::BaseError, ConnectionPool::Error => error
500+
rescue ::Redis::BaseError, ConnectionPool::Error, ConnectionPool::TimeoutError => error
501501
@error_handler&.call(method: method, exception: error, returning: returning)
502502
returning
503503
end

activesupport/test/cache/behaviors/connection_pool_behavior.rb

+32-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ def test_connection_pool
77
threads = []
88

99
emulating_latency do
10-
cache = ActiveSupport::Cache.lookup_store(*store, { pool: { size: 2, timeout: 1 } }.merge(store_options))
10+
cache = ActiveSupport::Cache.lookup_store(*store, { pool: { size: 2, timeout: 0.1 } }.merge(store_options))
1111
cache.read("foo")
1212

13-
assert_raises Timeout::Error do
13+
assert_nothing_raised do
1414
# One of the three threads will fail in 1 second because our pool size
1515
# is only two.
1616
3.times do
@@ -28,6 +28,36 @@ def test_connection_pool
2828
Thread.report_on_exception = original_report_on_exception
2929
end
3030

31+
def test_connection_pool_fetch
32+
Thread.report_on_exception, original_report_on_exception = false, Thread.report_on_exception
33+
34+
threads = []
35+
results = []
36+
37+
emulating_latency do
38+
cache = ActiveSupport::Cache.lookup_store(*store, { pool: { size: 2, timeout: 0.1 } }.merge(store_options))
39+
value = SecureRandom.alphanumeric
40+
base_key = "latency:#{SecureRandom.uuid}"
41+
42+
assert_nothing_raised do
43+
# One of the three threads will fail in 1 second because our pool size
44+
# is only two.
45+
3.times do |i|
46+
threads << Thread.new do
47+
cache.fetch("#{base_key}:#{i}") { value }
48+
end
49+
end
50+
51+
results = threads.map(&:value)
52+
assert_equal [value] * 3, results, "All threads should return the same value"
53+
end
54+
ensure
55+
threads.each(&:kill)
56+
end
57+
ensure
58+
Thread.report_on_exception = original_report_on_exception
59+
end
60+
3161
def test_no_connection_pool
3262
threads = []
3363

activesupport/test/cache/stores/redis_cache_store_test.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class SlowRedis < Redis
1111
def get(key)
1212
if /latency/.match?(key)
13-
sleep 3
13+
sleep 0.2
1414
super
1515
else
1616
super

0 commit comments

Comments
 (0)