legion-cache 1.3.21 → 1.4.1
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 +4 -4
- data/CHANGELOG.md +60 -0
- data/legion-cache.gemspec +1 -0
- data/lib/legion/cache/async_writer.rb +126 -0
- data/lib/legion/cache/cacheable.rb +4 -4
- data/lib/legion/cache/helper.rb +11 -11
- data/lib/legion/cache/local.rb +91 -29
- data/lib/legion/cache/memcached.rb +53 -40
- data/lib/legion/cache/memory.rb +107 -19
- data/lib/legion/cache/pool.rb +4 -1
- data/lib/legion/cache/reconnector.rb +108 -0
- data/lib/legion/cache/redis.rb +108 -47
- data/lib/legion/cache/redis_hash.rb +8 -8
- data/lib/legion/cache/settings.rb +52 -39
- data/lib/legion/cache/version.rb +1 -1
- data/lib/legion/cache.rb +310 -70
- metadata +17 -1
data/lib/legion/cache.rb
CHANGED
|
@@ -10,33 +10,77 @@ require 'legion/cache/redis'
|
|
|
10
10
|
require 'legion/cache/redis_hash'
|
|
11
11
|
require 'legion/cache/memory'
|
|
12
12
|
require 'legion/cache/local'
|
|
13
|
+
require 'legion/cache/async_writer'
|
|
14
|
+
require 'legion/cache/reconnector'
|
|
15
|
+
require 'concurrent'
|
|
13
16
|
require 'legion/cache/helper'
|
|
14
17
|
|
|
15
18
|
module Legion
|
|
16
19
|
module Cache
|
|
17
20
|
extend Legion::Logging::Helper
|
|
18
21
|
|
|
22
|
+
@async_writer = Legion::Cache::AsyncWriter.new(settings_key: :cache)
|
|
23
|
+
@connected = Concurrent::AtomicBoolean.new(false)
|
|
24
|
+
@using_local = Concurrent::AtomicBoolean.new(false)
|
|
25
|
+
@using_memory = Concurrent::AtomicBoolean.new(false)
|
|
26
|
+
|
|
19
27
|
class << self
|
|
20
28
|
include Legion::Logging::Helper
|
|
21
29
|
|
|
30
|
+
def enabled?
|
|
31
|
+
return true unless defined?(Legion::Settings)
|
|
32
|
+
|
|
33
|
+
Legion::Settings.dig(:cache, :enabled) != false
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
handle_exception(e, level: :warn, handled: true, operation: :cache_enabled)
|
|
36
|
+
true
|
|
37
|
+
end
|
|
38
|
+
|
|
22
39
|
def connected?
|
|
23
|
-
@connected
|
|
40
|
+
@connected&.true? || false
|
|
24
41
|
end
|
|
25
42
|
|
|
26
43
|
def driver_name
|
|
27
|
-
return 'memory' if
|
|
28
|
-
return 'local' if
|
|
44
|
+
return 'memory' if using_memory?
|
|
45
|
+
return 'local' if using_local?
|
|
29
46
|
|
|
30
47
|
@active_shared_driver || configured_shared_driver
|
|
31
48
|
end
|
|
32
49
|
|
|
50
|
+
def stats
|
|
51
|
+
{
|
|
52
|
+
driver: driver_name,
|
|
53
|
+
servers: resolved_servers,
|
|
54
|
+
enabled: enabled?,
|
|
55
|
+
connected: connected?,
|
|
56
|
+
using_local: using_local?,
|
|
57
|
+
using_memory: using_memory?,
|
|
58
|
+
pool_size: safe_pool_size,
|
|
59
|
+
pool_available: safe_pool_available,
|
|
60
|
+
async_pool_size: async_writer_pool_size,
|
|
61
|
+
async_queue_depth: async_writer_queue_depth,
|
|
62
|
+
async_processed: async_writer_processed_count,
|
|
63
|
+
async_failed: async_writer_failed_count,
|
|
64
|
+
reconnect_attempts: reconnector_attempts,
|
|
65
|
+
uptime: uptime_seconds
|
|
66
|
+
}.freeze
|
|
67
|
+
rescue StandardError => e
|
|
68
|
+
handle_exception(e, level: :warn, handled: true, operation: :cache_stats)
|
|
69
|
+
{ error: e.message }.freeze
|
|
70
|
+
end
|
|
71
|
+
|
|
33
72
|
def setup(**)
|
|
73
|
+
return unless enabled?
|
|
34
74
|
return Legion::Settings[:cache][:connected] = true if connected?
|
|
35
75
|
|
|
76
|
+
@setup_at = Time.now
|
|
77
|
+
|
|
78
|
+
async_writer.start
|
|
79
|
+
|
|
36
80
|
if ENV['LEGION_MODE'] == 'lite'
|
|
37
81
|
Legion::Cache::Memory.setup
|
|
38
|
-
@using_memory
|
|
39
|
-
@connected
|
|
82
|
+
@using_memory.make_true
|
|
83
|
+
@connected.make_true
|
|
40
84
|
Legion::Settings[:cache][:connected] = true
|
|
41
85
|
log.info 'Legion::Cache using in-memory adapter (lite mode)'
|
|
42
86
|
return
|
|
@@ -49,15 +93,20 @@ module Legion
|
|
|
49
93
|
|
|
50
94
|
def shutdown
|
|
51
95
|
log.info 'Shutting down Legion::Cache'
|
|
52
|
-
|
|
96
|
+
# 1. Drain async writer FIRST (while pool is still alive)
|
|
97
|
+
async_writer.stop(timeout: configured_shutdown_timeout)
|
|
98
|
+
# 2. Stop reconnector
|
|
99
|
+
stop_reconnector
|
|
100
|
+
# 3. Now close pools
|
|
101
|
+
if using_memory?
|
|
53
102
|
Legion::Cache::Memory.shutdown
|
|
54
103
|
else
|
|
55
|
-
close unless
|
|
104
|
+
close unless using_local?
|
|
56
105
|
Legion::Cache::Local.shutdown if Legion::Cache::Local.connected?
|
|
57
106
|
end
|
|
58
|
-
@using_local
|
|
59
|
-
@using_memory
|
|
60
|
-
@connected
|
|
107
|
+
@using_local.make_false
|
|
108
|
+
@using_memory.make_false
|
|
109
|
+
@connected.make_false
|
|
61
110
|
Legion::Settings[:cache][:connected] = false
|
|
62
111
|
end
|
|
63
112
|
|
|
@@ -65,44 +114,53 @@ module Legion
|
|
|
65
114
|
Legion::Cache::Local
|
|
66
115
|
end
|
|
67
116
|
|
|
117
|
+
def pool
|
|
118
|
+
@client
|
|
119
|
+
end
|
|
120
|
+
|
|
68
121
|
def using_local?
|
|
69
|
-
@using_local
|
|
122
|
+
@using_local&.true? || false
|
|
70
123
|
end
|
|
71
124
|
|
|
72
125
|
def using_memory?
|
|
73
|
-
@using_memory
|
|
126
|
+
@using_memory&.true? || false
|
|
74
127
|
end
|
|
75
128
|
|
|
76
129
|
def client(**opts)
|
|
77
130
|
if ENV['LEGION_MODE'] == 'lite'
|
|
78
131
|
Legion::Cache::Memory.setup unless Legion::Cache::Memory.connected?
|
|
79
|
-
@using_memory
|
|
80
|
-
@using_local
|
|
81
|
-
@connected
|
|
132
|
+
@using_memory.make_true
|
|
133
|
+
@using_local.make_false
|
|
134
|
+
@connected.make_true
|
|
82
135
|
@active_shared_driver = nil
|
|
83
136
|
Legion::Settings[:cache][:connected] = true if defined?(Legion::Settings)
|
|
84
137
|
return Legion::Cache::Memory.client
|
|
85
138
|
end
|
|
86
139
|
|
|
87
140
|
configure_shared_adapter!(opts[:driver])
|
|
88
|
-
@using_memory
|
|
89
|
-
@using_local
|
|
141
|
+
@using_memory.make_false
|
|
142
|
+
@using_local.make_false
|
|
90
143
|
result = super
|
|
91
|
-
@connected
|
|
144
|
+
# super (Pool) sets @connected to a plain boolean; restore AtomicBoolean
|
|
145
|
+
@connected = Concurrent::AtomicBoolean.new(true)
|
|
92
146
|
Legion::Settings[:cache][:connected] = true if defined?(Legion::Settings)
|
|
93
147
|
result
|
|
94
148
|
rescue StandardError
|
|
95
|
-
@connected = false
|
|
149
|
+
@connected = Concurrent::AtomicBoolean.new(false)
|
|
96
150
|
Legion::Settings[:cache][:connected] = false if defined?(Legion::Settings)
|
|
97
151
|
raise
|
|
98
152
|
end
|
|
99
153
|
|
|
100
154
|
def get(key)
|
|
101
|
-
return Legion::Cache::Memory.get(key) if
|
|
102
|
-
return Legion::Cache::Local.get(key) if
|
|
155
|
+
return Legion::Cache::Memory.get(key) if using_memory?
|
|
156
|
+
return Legion::Cache::Local.get(key) if using_local?
|
|
157
|
+
return Legion::Cache::Local.get(key) if failback_to_local?
|
|
103
158
|
|
|
104
159
|
configure_shared_adapter!
|
|
105
160
|
super
|
|
161
|
+
rescue StandardError => e
|
|
162
|
+
handle_exception(e, level: :warn, handled: true, operation: :cache_get, key: key)
|
|
163
|
+
nil
|
|
106
164
|
end
|
|
107
165
|
|
|
108
166
|
def phi_max_ttl
|
|
@@ -121,35 +179,57 @@ module Legion
|
|
|
121
179
|
[ttl, max].min
|
|
122
180
|
end
|
|
123
181
|
|
|
124
|
-
def set(key, value, ttl
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
182
|
+
def set(key, value, ttl: nil, async: true, phi: false)
|
|
183
|
+
effective_ttl = resolve_ttl(ttl, phi: phi)
|
|
184
|
+
|
|
185
|
+
if async && async_writer.running?
|
|
186
|
+
async_writer.enqueue { set_internal(key, value, ttl: effective_ttl) }
|
|
187
|
+
true
|
|
188
|
+
else
|
|
189
|
+
set_internal(key, value, ttl: effective_ttl)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def set_sync(key, value, ttl: nil, **)
|
|
194
|
+
return Legion::Cache::Memory.set_sync(key, value, ttl: ttl) if using_memory?
|
|
195
|
+
return Legion::Cache::Local.set_sync(key, value, ttl: ttl) if using_local?
|
|
196
|
+
return Legion::Cache::Local.set_sync(key, value, ttl: ttl) if failback_to_local?
|
|
129
197
|
|
|
130
198
|
configure_shared_adapter!
|
|
131
|
-
super
|
|
199
|
+
super
|
|
132
200
|
end
|
|
133
201
|
|
|
134
|
-
def fetch(key, ttl
|
|
135
|
-
return Legion::Cache::Memory.fetch(key, ttl, &) if
|
|
136
|
-
return Legion::Cache::Local.fetch(key, ttl, &) if
|
|
202
|
+
def fetch(key, ttl: nil, &)
|
|
203
|
+
return Legion::Cache::Memory.fetch(key, ttl: ttl, &) if using_memory?
|
|
204
|
+
return Legion::Cache::Local.fetch(key, ttl: ttl, &) if using_local?
|
|
205
|
+
return Legion::Cache::Local.fetch(key, ttl: ttl, &) if failback_to_local?
|
|
137
206
|
|
|
138
207
|
configure_shared_adapter!
|
|
139
208
|
super
|
|
140
209
|
end
|
|
141
210
|
|
|
142
|
-
def delete(key)
|
|
143
|
-
|
|
144
|
-
|
|
211
|
+
def delete(key, async: true)
|
|
212
|
+
if async && async_writer.running?
|
|
213
|
+
async_writer.enqueue { delete_internal(key) }
|
|
214
|
+
true
|
|
215
|
+
else
|
|
216
|
+
delete_internal(key)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def delete_sync(key)
|
|
221
|
+
return Legion::Cache::Memory.delete_sync(key) if using_memory?
|
|
222
|
+
return Legion::Cache::Local.delete_sync(key) if using_local?
|
|
223
|
+
return Legion::Cache::Local.delete_sync(key) if failback_to_local?
|
|
145
224
|
|
|
146
225
|
configure_shared_adapter!
|
|
147
226
|
super
|
|
148
227
|
end
|
|
149
228
|
|
|
150
|
-
def flush
|
|
151
|
-
return Legion::Cache::Memory.flush
|
|
152
|
-
return Legion::Cache::Local.flush
|
|
229
|
+
def flush
|
|
230
|
+
return Legion::Cache::Memory.flush if using_memory?
|
|
231
|
+
return Legion::Cache::Local.flush if using_local?
|
|
232
|
+
return Legion::Cache::Local.flush if failback_to_local?
|
|
153
233
|
|
|
154
234
|
configure_shared_adapter!
|
|
155
235
|
super
|
|
@@ -158,35 +238,48 @@ module Legion
|
|
|
158
238
|
def mget(*keys)
|
|
159
239
|
keys = keys.flatten
|
|
160
240
|
return {} if keys.empty?
|
|
161
|
-
return keys.to_h { |key| [key, Legion::Cache::Memory.get(key)] } if
|
|
162
|
-
return
|
|
241
|
+
return keys.to_h { |key| [key, Legion::Cache::Memory.get(key)] } if using_memory?
|
|
242
|
+
return Legion::Cache::Local.mget(*keys) if using_local?
|
|
243
|
+
return Legion::Cache::Local.mget(*keys) if failback_to_local?
|
|
163
244
|
|
|
164
245
|
configure_shared_adapter!
|
|
165
246
|
super
|
|
166
247
|
end
|
|
167
248
|
|
|
168
|
-
def mset(hash)
|
|
249
|
+
def mset(hash, ttl: nil, async: true)
|
|
169
250
|
return true if hash.empty?
|
|
170
|
-
|
|
171
|
-
|
|
251
|
+
|
|
252
|
+
if async && async_writer.running?
|
|
253
|
+
async_writer.enqueue { mset_internal(hash, ttl: ttl) }
|
|
254
|
+
true
|
|
255
|
+
else
|
|
256
|
+
mset_internal(hash, ttl: ttl)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def mset_sync(hash, ttl: nil, **)
|
|
261
|
+
return true if hash.empty?
|
|
262
|
+
return hash.each { |key, value| Legion::Cache::Memory.set_sync(key, value, ttl: ttl) } && true if using_memory?
|
|
263
|
+
return Legion::Cache::Local.mset(hash, ttl: ttl) if using_local?
|
|
264
|
+
return Legion::Cache::Local.mset(hash, ttl: ttl) if failback_to_local?
|
|
172
265
|
|
|
173
266
|
configure_shared_adapter!
|
|
174
267
|
super
|
|
175
268
|
end
|
|
176
269
|
|
|
177
270
|
def close
|
|
178
|
-
if
|
|
271
|
+
if using_memory?
|
|
179
272
|
Legion::Cache::Memory.shutdown
|
|
180
|
-
@using_memory
|
|
181
|
-
@connected
|
|
273
|
+
@using_memory.make_false
|
|
274
|
+
@connected.make_false
|
|
182
275
|
Legion::Settings[:cache][:connected] = false if defined?(Legion::Settings)
|
|
183
276
|
return false
|
|
184
277
|
end
|
|
185
278
|
|
|
186
|
-
if
|
|
279
|
+
if using_local?
|
|
187
280
|
Legion::Cache::Local.close
|
|
188
|
-
@using_local
|
|
189
|
-
@connected
|
|
281
|
+
@using_local.make_false
|
|
282
|
+
@connected.make_false
|
|
190
283
|
Legion::Settings[:cache][:connected] = false if defined?(Legion::Settings)
|
|
191
284
|
return false
|
|
192
285
|
end
|
|
@@ -195,48 +288,48 @@ module Legion
|
|
|
195
288
|
|
|
196
289
|
configure_shared_adapter!
|
|
197
290
|
result = super
|
|
198
|
-
@connected = false
|
|
291
|
+
@connected = Concurrent::AtomicBoolean.new(false)
|
|
199
292
|
Legion::Settings[:cache][:connected] = false if defined?(Legion::Settings)
|
|
200
293
|
result
|
|
201
294
|
end
|
|
202
295
|
|
|
203
296
|
def restart(**opts)
|
|
204
297
|
configure_shared_adapter!(opts[:driver])
|
|
205
|
-
@using_memory
|
|
206
|
-
@using_local
|
|
298
|
+
@using_memory.make_false
|
|
299
|
+
@using_local.make_false
|
|
207
300
|
result = super
|
|
208
|
-
@connected = true
|
|
301
|
+
@connected = Concurrent::AtomicBoolean.new(true)
|
|
209
302
|
Legion::Settings[:cache][:connected] = true if defined?(Legion::Settings)
|
|
210
303
|
result
|
|
211
304
|
end
|
|
212
305
|
|
|
213
306
|
def size
|
|
214
|
-
return Legion::Cache::Memory.size if
|
|
215
|
-
return Legion::Cache::Local.size if
|
|
307
|
+
return Legion::Cache::Memory.size if using_memory?
|
|
308
|
+
return Legion::Cache::Local.size if using_local?
|
|
216
309
|
|
|
217
310
|
configure_shared_adapter!
|
|
218
311
|
super
|
|
219
312
|
end
|
|
220
313
|
|
|
221
314
|
def available
|
|
222
|
-
return Legion::Cache::Memory.available if
|
|
223
|
-
return Legion::Cache::Local.available if
|
|
315
|
+
return Legion::Cache::Memory.available if using_memory?
|
|
316
|
+
return Legion::Cache::Local.available if using_local?
|
|
224
317
|
|
|
225
318
|
configure_shared_adapter!
|
|
226
319
|
super
|
|
227
320
|
end
|
|
228
321
|
|
|
229
322
|
def pool_size
|
|
230
|
-
return Legion::Cache::Memory.size if
|
|
231
|
-
return Legion::Cache::Local.pool_size if
|
|
323
|
+
return Legion::Cache::Memory.size if using_memory?
|
|
324
|
+
return Legion::Cache::Local.pool_size if using_local?
|
|
232
325
|
|
|
233
326
|
configure_shared_adapter!
|
|
234
327
|
super
|
|
235
328
|
end
|
|
236
329
|
|
|
237
330
|
def timeout
|
|
238
|
-
return 0 if
|
|
239
|
-
return Legion::Cache::Local.timeout if
|
|
331
|
+
return 0 if using_memory?
|
|
332
|
+
return Legion::Cache::Local.timeout if using_local?
|
|
240
333
|
|
|
241
334
|
configure_shared_adapter!
|
|
242
335
|
super
|
|
@@ -244,6 +337,64 @@ module Legion
|
|
|
244
337
|
|
|
245
338
|
private
|
|
246
339
|
|
|
340
|
+
def async_writer
|
|
341
|
+
Legion::Cache.instance_variable_get(:@async_writer)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def set_internal(key, value, ttl: nil)
|
|
345
|
+
return Legion::Cache::Memory.set(key, value, ttl: ttl) if using_memory?
|
|
346
|
+
return Legion::Cache::Local.set(key, value, ttl: ttl) if using_local?
|
|
347
|
+
return Legion::Cache::Local.set(key, value, ttl: ttl) if failback_to_local?
|
|
348
|
+
|
|
349
|
+
configure_shared_adapter!
|
|
350
|
+
set_sync(key, value, ttl: ttl)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def delete_internal(key)
|
|
354
|
+
return Legion::Cache::Memory.delete(key) if using_memory?
|
|
355
|
+
return Legion::Cache::Local.delete(key) if using_local?
|
|
356
|
+
return Legion::Cache::Local.delete(key) if failback_to_local?
|
|
357
|
+
|
|
358
|
+
configure_shared_adapter!
|
|
359
|
+
delete_sync(key)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def mset_internal(hash, ttl: nil)
|
|
363
|
+
return hash.each { |key, value| Legion::Cache::Memory.set(key, value, ttl: ttl) } && true if using_memory?
|
|
364
|
+
return Legion::Cache::Local.mset(hash, ttl: ttl) if using_local?
|
|
365
|
+
return Legion::Cache::Local.mset(hash, ttl: ttl) if failback_to_local?
|
|
366
|
+
|
|
367
|
+
configure_shared_adapter!
|
|
368
|
+
mset_sync(hash, ttl: ttl)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def failback_to_local?
|
|
372
|
+
return false unless Legion::Cache::Local.connected?
|
|
373
|
+
|
|
374
|
+
setting = if defined?(Legion::Settings)
|
|
375
|
+
Legion::Settings.dig(:cache, :failback_to_local) != false
|
|
376
|
+
else
|
|
377
|
+
true
|
|
378
|
+
end
|
|
379
|
+
setting && (!enabled? || !connected?)
|
|
380
|
+
rescue StandardError => e
|
|
381
|
+
handle_exception(e, level: :warn, handled: true, operation: :cache_failback_check)
|
|
382
|
+
false
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def resolve_ttl(ttl, phi: false)
|
|
386
|
+
effective = ttl || default_ttl
|
|
387
|
+
enforce_phi_ttl(effective, phi: phi)
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def default_ttl
|
|
391
|
+
return 3600 unless defined?(Legion::Settings)
|
|
392
|
+
|
|
393
|
+
Legion::Settings.dig(:cache, :default_ttl) || 3600
|
|
394
|
+
rescue StandardError
|
|
395
|
+
3600
|
|
396
|
+
end
|
|
397
|
+
|
|
247
398
|
def setup_local
|
|
248
399
|
return if Legion::Cache::Local.connected?
|
|
249
400
|
|
|
@@ -254,8 +405,8 @@ module Legion
|
|
|
254
405
|
|
|
255
406
|
def setup_shared(**)
|
|
256
407
|
client(**Legion::Settings[:cache], logger: log, **)
|
|
257
|
-
@connected
|
|
258
|
-
@using_local
|
|
408
|
+
@connected.make_true
|
|
409
|
+
@using_local.make_false
|
|
259
410
|
Legion::Settings[:cache][:connected] = true
|
|
260
411
|
driver = Legion::Settings[:cache][:driver] || 'dalli'
|
|
261
412
|
servers = Array(Legion::Settings[:cache][:servers]).join(', ')
|
|
@@ -263,15 +414,24 @@ module Legion
|
|
|
263
414
|
rescue StandardError => e
|
|
264
415
|
report_exception(e, level: :warn, handled: true, operation: :setup_shared, fallback: :local)
|
|
265
416
|
if Legion::Cache::Local.connected?
|
|
266
|
-
@using_local
|
|
267
|
-
@connected
|
|
417
|
+
@using_local.make_true
|
|
418
|
+
@connected.make_true
|
|
268
419
|
Legion::Settings[:cache][:connected] = true
|
|
269
420
|
log.info 'Legion::Cache fell back to Local cache'
|
|
270
421
|
else
|
|
271
|
-
@connected
|
|
422
|
+
@connected.make_false
|
|
272
423
|
Legion::Settings[:cache][:connected] = false
|
|
273
424
|
log.error 'Legion::Cache shared and local adapters are unavailable'
|
|
274
425
|
end
|
|
426
|
+
start_reconnector if enabled?
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def reconnect_shared!
|
|
430
|
+
client(**Legion::Settings[:cache], logger: log)
|
|
431
|
+
@connected.make_true
|
|
432
|
+
@using_local.make_false
|
|
433
|
+
Legion::Settings[:cache][:connected] = true
|
|
434
|
+
log.info 'Legion::Cache shared reconnected'
|
|
275
435
|
end
|
|
276
436
|
|
|
277
437
|
def report_exception(exception, level:, handled:, **)
|
|
@@ -317,16 +477,96 @@ module Legion
|
|
|
317
477
|
handle_exception(e, level: :warn, handled: true, operation: :cache_close_existing_shared_client)
|
|
318
478
|
ensure
|
|
319
479
|
@client = nil
|
|
320
|
-
@connected = false
|
|
480
|
+
@connected = Concurrent::AtomicBoolean.new(false)
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def resolved_servers
|
|
484
|
+
return [] if using_memory?
|
|
485
|
+
|
|
486
|
+
Array(Legion::Settings.dig(:cache, :servers))
|
|
487
|
+
rescue StandardError
|
|
488
|
+
[]
|
|
321
489
|
end
|
|
322
490
|
|
|
323
|
-
def
|
|
324
|
-
|
|
491
|
+
def safe_pool_size
|
|
492
|
+
return 1 if using_memory?
|
|
493
|
+
return 0 unless connected?
|
|
494
|
+
|
|
495
|
+
pool_size
|
|
496
|
+
rescue StandardError
|
|
497
|
+
0
|
|
325
498
|
end
|
|
326
499
|
|
|
327
|
-
def
|
|
328
|
-
|
|
329
|
-
|
|
500
|
+
def safe_pool_available
|
|
501
|
+
return 1 if using_memory?
|
|
502
|
+
return 0 unless connected?
|
|
503
|
+
|
|
504
|
+
available
|
|
505
|
+
rescue StandardError
|
|
506
|
+
0
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def async_writer_pool_size
|
|
510
|
+
async_writer.pool_size
|
|
511
|
+
rescue StandardError
|
|
512
|
+
0
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def async_writer_queue_depth
|
|
516
|
+
async_writer.queue_depth
|
|
517
|
+
rescue StandardError
|
|
518
|
+
0
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def async_writer_processed_count
|
|
522
|
+
async_writer.processed_count
|
|
523
|
+
rescue StandardError
|
|
524
|
+
0
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def configured_shutdown_timeout
|
|
528
|
+
return 5 unless defined?(Legion::Settings)
|
|
529
|
+
|
|
530
|
+
Legion::Settings.dig(:cache, :async, :shutdown_timeout) || 5
|
|
531
|
+
rescue StandardError
|
|
532
|
+
5
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def async_writer_failed_count
|
|
536
|
+
async_writer.failed_count
|
|
537
|
+
rescue StandardError
|
|
538
|
+
0
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def reconnector_attempts
|
|
542
|
+
@reconnector&.attempts || 0
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
def start_reconnector
|
|
546
|
+
return unless enabled?
|
|
547
|
+
|
|
548
|
+
stop_reconnector
|
|
549
|
+
@reconnector = Legion::Cache::Reconnector.new(
|
|
550
|
+
tier: :shared,
|
|
551
|
+
connect_block: -> { reconnect_shared! },
|
|
552
|
+
enabled_block: -> { enabled? },
|
|
553
|
+
settings_key: :cache
|
|
554
|
+
)
|
|
555
|
+
@reconnector.start
|
|
556
|
+
log.info 'Legion::Cache started background reconnector for shared tier'
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def stop_reconnector
|
|
560
|
+
@reconnector&.stop
|
|
561
|
+
@reconnector = nil
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
def uptime_seconds
|
|
565
|
+
return 0 unless @setup_at
|
|
566
|
+
|
|
567
|
+
(Time.now - @setup_at).to_i
|
|
568
|
+
rescue StandardError
|
|
569
|
+
0
|
|
330
570
|
end
|
|
331
571
|
end
|
|
332
572
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-cache
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: concurrent-ruby
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.2'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.2'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: connection_pool
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -102,12 +116,14 @@ files:
|
|
|
102
116
|
- README.md
|
|
103
117
|
- legion-cache.gemspec
|
|
104
118
|
- lib/legion/cache.rb
|
|
119
|
+
- lib/legion/cache/async_writer.rb
|
|
105
120
|
- lib/legion/cache/cacheable.rb
|
|
106
121
|
- lib/legion/cache/helper.rb
|
|
107
122
|
- lib/legion/cache/local.rb
|
|
108
123
|
- lib/legion/cache/memcached.rb
|
|
109
124
|
- lib/legion/cache/memory.rb
|
|
110
125
|
- lib/legion/cache/pool.rb
|
|
126
|
+
- lib/legion/cache/reconnector.rb
|
|
111
127
|
- lib/legion/cache/redis.rb
|
|
112
128
|
- lib/legion/cache/redis_hash.rb
|
|
113
129
|
- lib/legion/cache/settings.rb
|