redis-memo 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 976988ff54686693396ffb07c47b9e4326646837b3be53264891c886f03771c6
4
- data.tar.gz: 9e4a3d4dca78cb9389af8e1728addb3aa8d04493365bcfda2ea236e20c657971
3
+ metadata.gz: 9d4fa9d940a295287a258f88f3cbc44498a6e5475a58c0cdb8e5e320d2793652
4
+ data.tar.gz: bbe225fc22a568c3de716feba66b3a1fbbdeb52a1ef4c2c4a47b94bbfa8a33cb
5
5
  SHA512:
6
- metadata.gz: 118d801be413e14616becfb3a9c4e4715a1e7b7cb6722ac48bd8b1c63e6b1c8f565c8a148909b4bd7b4b538f89d1d79145ad137403139eb7158cad61c9d7a847
7
- data.tar.gz: 52bdf762fc8bf22a6b65fc158512e001dd12490904db9766cd9f3ff1aee74e61f23f218bfa46cdf57fdb67f9f0d2508649fedc2379d6224d0d34416ffbafb902
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
@@ -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
- ::ConnectionPool::TimeoutError
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
- result = @app.call(env)
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
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-memo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chan Zuckerberg Initiative