redis-memo 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4fa9d940a295287a258f88f3cbc44498a6e5475a58c0cdb8e5e320d2793652
|
4
|
+
data.tar.gz: bbe225fc22a568c3de716feba66b3a1fbbdeb52a1ef4c2c4a47b94bbfa8a33cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d5ec94adc1f74479690f5dc95eb7459b777de63827baa59302931287222266d33def750d9649c8c8e37a4fd43d95c7fac7c79b8ec012848f51ae5fad5f5ec91
|
7
|
+
data.tar.gz: 2219225dea50042b8f99dadcdad44f367d48c74573d3ac29ef0e4060c0dc7fee13a58034420229386bd16b408f6797718714e15af2710a954ad89964e7c21d5d
|
data/lib/redis_memo.rb
CHANGED
@@ -19,6 +19,8 @@ module RedisMemo
|
|
19
19
|
|
20
20
|
# @todo Move thread keys to +RedisMemo::ThreadKey+
|
21
21
|
THREAD_KEY_WITHOUT_MEMO = :__redis_memo_without_memo__
|
22
|
+
THREAD_KEY_CONNECTION_ATTEMPTS_COUNT = :__redis_memo_connection_attempts_count__
|
23
|
+
THREAD_KEY_MAX_CONNECTION_ATTEMPTS = :__redis_memo_max_connection_attempts__
|
22
24
|
|
23
25
|
# Configure global-level default options. Those options will be used unless
|
24
26
|
# some options specified at +memoize_method+ callsite level. See
|
@@ -80,7 +82,7 @@ module RedisMemo
|
|
80
82
|
#
|
81
83
|
# @return [Boolean]
|
82
84
|
def self.without_memo?
|
83
|
-
Thread.current[THREAD_KEY_WITHOUT_MEMO] == true
|
85
|
+
ENV["REDIS_MEMO_DISABLE_ALL"] == 'true' || Thread.current[THREAD_KEY_WITHOUT_MEMO] == true
|
84
86
|
end
|
85
87
|
|
86
88
|
# Configure the wrapped code in the block to skip memoization.
|
@@ -94,6 +96,35 @@ module RedisMemo
|
|
94
96
|
Thread.current[THREAD_KEY_WITHOUT_MEMO] = prev_value
|
95
97
|
end
|
96
98
|
|
99
|
+
# Set the max connection attempts to Redis per code block. If we fail to connect to Redis more than `max_attempts`
|
100
|
+
# times, the rest of the code block will fall back to the uncached flow, `RedisMemo.without_memo`.
|
101
|
+
#
|
102
|
+
# @param [Integer] The max number of connection attempts.
|
103
|
+
# @yield [] no_args the block of code to set the max attempts for.
|
104
|
+
def self.with_max_connection_attempts(max_attempts)
|
105
|
+
prev_value = Thread.current[THREAD_KEY_WITHOUT_MEMO]
|
106
|
+
if max_attempts
|
107
|
+
Thread.current[THREAD_KEY_CONNECTION_ATTEMPTS_COUNT] = 0
|
108
|
+
Thread.current[THREAD_KEY_MAX_CONNECTION_ATTEMPTS] = max_attempts
|
109
|
+
end
|
110
|
+
yield
|
111
|
+
ensure
|
112
|
+
Thread.current[THREAD_KEY_WITHOUT_MEMO] = prev_value
|
113
|
+
Thread.current[THREAD_KEY_CONNECTION_ATTEMPTS_COUNT] = nil
|
114
|
+
Thread.current[THREAD_KEY_MAX_CONNECTION_ATTEMPTS] = nil
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def self.incr_connection_attempts # :nodoc:
|
119
|
+
return if Thread.current[THREAD_KEY_MAX_CONNECTION_ATTEMPTS].nil? || Thread.current[THREAD_KEY_CONNECTION_ATTEMPTS_COUNT].nil?
|
120
|
+
|
121
|
+
# The connection attempts count and max connection attempts are reset in RedisMemo.with_max_connection_attempts
|
122
|
+
Thread.current[THREAD_KEY_CONNECTION_ATTEMPTS_COUNT] += 1
|
123
|
+
if Thread.current[THREAD_KEY_CONNECTION_ATTEMPTS_COUNT] >= Thread.current[THREAD_KEY_MAX_CONNECTION_ATTEMPTS]
|
124
|
+
Thread.current[THREAD_KEY_WITHOUT_MEMO] = true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
97
128
|
# @todo Move errors to a separate file errors.rb
|
98
129
|
class ArgumentError < ::ArgumentError; end
|
99
130
|
class RuntimeError < ::RuntimeError; end
|
data/lib/redis_memo/cache.rb
CHANGED
@@ -17,6 +17,8 @@ class RedisMemo::Cache < ActiveSupport::Cache::RedisCacheStore
|
|
17
17
|
RedisMemo::DefaultOptions.redis_error_handler&.call(exception, method)
|
18
18
|
RedisMemo::DefaultOptions.logger&.warn(exception.full_message)
|
19
19
|
|
20
|
+
RedisMemo.incr_connection_attempts if exception.is_a?(Redis::BaseConnectionError)
|
21
|
+
|
20
22
|
if Thread.current[THREAD_KEY_RAISE_ERROR]
|
21
23
|
raise RedisMemo::Cache::Rescuable
|
22
24
|
else
|
@@ -50,9 +50,12 @@ class RedisMemo::Memoizable::Dependency
|
|
50
50
|
private
|
51
51
|
|
52
52
|
def self.extract_from_relation(relation)
|
53
|
+
connection = ActiveRecord::Base.connection
|
54
|
+
unless connection.respond_to?(:dependency_of)
|
55
|
+
raise RedisMemo::WithoutMemoization, 'Caching active record queries is currently disabled on RedisMemo'
|
56
|
+
end
|
53
57
|
# Extract the dependent memos of an Arel without calling exec_query to actually execute the query
|
54
58
|
RedisMemo::MemoizeQuery::CachedSelect.with_new_query_context do
|
55
|
-
connection = ActiveRecord::Base.connection
|
56
59
|
query, binds, _ = connection.send(:to_sql_and_binds, relation.arel)
|
57
60
|
RedisMemo::MemoizeQuery::CachedSelect.current_query = relation.arel
|
58
61
|
is_query_cached = RedisMemo::MemoizeQuery::CachedSelect.extract_bind_params(query)
|
@@ -127,7 +127,10 @@ module RedisMemo::Memoizable::Invalidation
|
|
127
127
|
begin
|
128
128
|
bump_version(task)
|
129
129
|
rescue SignalException, Redis::BaseConnectionError,
|
130
|
-
|
130
|
+
::ConnectionPool::TimeoutError => e
|
131
|
+
|
132
|
+
RedisMemo::DefaultOptions.redis_error_handler&.call(e, __method__)
|
133
|
+
RedisMemo::DefaultOptions.logger&.warn(e.full_message)
|
131
134
|
retry_queue << task
|
132
135
|
end
|
133
136
|
end
|
@@ -13,6 +13,7 @@ if defined?(ActiveRecord)
|
|
13
13
|
# after each record save
|
14
14
|
def memoize_table_column(*raw_columns, editable: true)
|
15
15
|
RedisMemo::MemoizeQuery.using_active_record!(self)
|
16
|
+
return if ENV["REDIS_MEMO_DISABLE_ALL"] == 'true'
|
16
17
|
return if ENV["REDIS_MEMO_DISABLE_#{self.table_name.upcase}"] == 'true'
|
17
18
|
|
18
19
|
columns = raw_columns.map(&:to_sym).sort
|
@@ -9,7 +9,9 @@ class RedisMemo::Middleware
|
|
9
9
|
result = nil
|
10
10
|
|
11
11
|
RedisMemo::Cache.with_local_cache do
|
12
|
-
|
12
|
+
RedisMemo.with_max_connection_attempts(ENV['REDIS_MEMO_MAX_ATTEMPTS_PER_REQUEST']&.to_i) do
|
13
|
+
result = @app.call(env)
|
14
|
+
end
|
13
15
|
end
|
14
16
|
RedisMemo::Memoizable::Invalidation.drain_invalidation_queue
|
15
17
|
|