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: 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