redis_queued_locks 1.6.0 → 1.7.0
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 +9 -1
- data/README.md +141 -53
- data/lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +36 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue.rb +39 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/instr_visitor.rb +151 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/log_visitor.rb +192 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock/log_visitor.rb +485 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb +73 -198
- data/lib/redis_queued_locks/acquier/acquire_lock/yield_expire/log_visitor.rb +68 -0
- data/lib/redis_queued_locks/acquier/acquire_lock/yield_expire.rb +13 -22
- data/lib/redis_queued_locks/acquier/acquire_lock.rb +83 -110
- data/lib/redis_queued_locks/client.rb +23 -2
- data/lib/redis_queued_locks/utilities.rb +0 -1
- data/lib/redis_queued_locks/version.rb +2 -2
- data/lib/redis_queued_locks/watcher.rb +1 -0
- data/redis_queued_locks.gemspec +23 -3
- metadata +13 -5
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 1.0.0
|
5
|
+
# @version 1.7.0
|
5
6
|
# rubocop:disable Metrics/ModuleLength, Metrics/BlockNesting
|
6
7
|
module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
7
|
-
|
8
|
-
extend RedisQueuedLocks::Utilities
|
8
|
+
require_relative 'try_to_lock/log_visitor'
|
9
9
|
|
10
10
|
# @return [String]
|
11
11
|
#
|
@@ -27,6 +27,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
27
27
|
# @param queue_ttl [Integer]
|
28
28
|
# @param fail_fast [Boolean]
|
29
29
|
# @param conflict_strategy [Symbol]
|
30
|
+
# @param access_strategy [Symbol]
|
30
31
|
# @param meta [NilClass,Hash<String|Symbol,Any>]
|
31
32
|
# @param log_sampled [Boolean]
|
32
33
|
# @param instr_sampled [Boolean]
|
@@ -34,7 +35,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
34
35
|
#
|
35
36
|
# @api private
|
36
37
|
# @since 1.0.0
|
37
|
-
# @version 1.
|
38
|
+
# @version 1.7.0
|
38
39
|
# rubocop:disable Metrics/MethodLength
|
39
40
|
def try_to_lock(
|
40
41
|
redis,
|
@@ -48,6 +49,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
48
49
|
queue_ttl,
|
49
50
|
fail_fast,
|
50
51
|
conflict_strategy,
|
52
|
+
access_strategy,
|
51
53
|
meta,
|
52
54
|
log_sampled,
|
53
55
|
instr_sampled
|
@@ -57,29 +59,17 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
57
59
|
timestamp = nil
|
58
60
|
spc_processed_timestamp = nil
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
"lock_key => '#{lock_key}' " \
|
65
|
-
"queue_ttl => #{queue_ttl} " \
|
66
|
-
"acq_id => '#{acquier_id}'"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
62
|
+
LogVisitor.start(
|
63
|
+
logger, log_sampled, log_lock_try,
|
64
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
65
|
+
)
|
70
66
|
|
71
67
|
# Step X: start to work with lock acquiring
|
72
68
|
result = redis.with do |rconn|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
"lock_key => '#{lock_key}' " \
|
78
|
-
"queue_ttl => #{queue_ttl} " \
|
79
|
-
"acq_id => '#{acquier_id}'"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
69
|
+
LogVisitor.rconn_fetched(
|
70
|
+
logger, log_sampled, log_lock_try,
|
71
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
72
|
+
)
|
83
73
|
|
84
74
|
# Step 0:
|
85
75
|
# watch the lock key changes (and discard acquirement if lock is already
|
@@ -92,16 +82,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
92
82
|
|
93
83
|
# SP-Conflict Step X1: calculate the current deadlock status
|
94
84
|
if current_lock_obtainer != nil && acquier_id == current_lock_obtainer
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
"lock_key => '#{lock_key}' " \
|
100
|
-
"queue_ttl => #{queue_ttl} " \
|
101
|
-
"acq_id => '#{acquier_id}'"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
85
|
+
LogVisitor.same_process_conflict_detected(
|
86
|
+
logger, log_sampled, log_lock_try,
|
87
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
88
|
+
)
|
105
89
|
|
106
90
|
# SP-Conflict Step X2: self-process dead lock moment started.
|
107
91
|
# SP-Conflict CHECK (Step CHECK): check chosen strategy and flag the current status
|
@@ -128,17 +112,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
128
112
|
end
|
129
113
|
# rubocop:enable Lint/DuplicateBranch
|
130
114
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
"lock_key => '#{lock_key}' " \
|
136
|
-
"queue_ttl => #{queue_ttl} " \
|
137
|
-
"acq_id => '#{acquier_id}' " \
|
138
|
-
"spc_status => '#{sp_conflict_status}'"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
115
|
+
LogVisitor.same_process_conflict_analyzed(
|
116
|
+
logger, log_sampled, log_lock_try,
|
117
|
+
lock_key, queue_ttl, acquier_id, access_strategy, sp_conflict_status
|
118
|
+
)
|
142
119
|
end
|
143
120
|
|
144
121
|
# SP-Conflict-Step X2: switch to conflict-based logic or not
|
@@ -176,19 +153,11 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
176
153
|
)
|
177
154
|
inter_result = :extendable_conflict_work_through
|
178
155
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
"queue_ttl => #{queue_ttl} " \
|
185
|
-
"acq_id => '#{acquier_id}'" \
|
186
|
-
"spc_status => '#{sp_conflict_status} '" \
|
187
|
-
"last_ext_ttl => '#{ttl}' " \
|
188
|
-
"last_ext_ts => '#{spc_processed_timestamp}'"
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
156
|
+
LogVisitor.reentrant_lock__extend_and_work_through(
|
157
|
+
logger, log_sampled, log_lock_try,
|
158
|
+
lock_key, queue_ttl, acquier_id, access_strategy,
|
159
|
+
sp_conflict_status, ttl, spc_processed_timestamp
|
160
|
+
)
|
192
161
|
# SP-Conflict-Step X2: switch to dead lock logic or not
|
193
162
|
elsif sp_conflict_status == :conflict_work_through
|
194
163
|
inter_result = :conflict_work_through
|
@@ -209,33 +178,21 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
209
178
|
'l_spc_ts', (spc_processed_timestamp = Time.now.to_f)
|
210
179
|
)
|
211
180
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
"queue_ttl => #{queue_ttl} " \
|
218
|
-
"acq_id => '#{acquier_id}' " \
|
219
|
-
"spc_status => '#{sp_conflict_status} ' " \
|
220
|
-
"last_spc_ts => '#{spc_processed_timestamp}'"
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
181
|
+
LogVisitor.reentrant_lock__work_through(
|
182
|
+
logger, log_sampled, log_lock_try,
|
183
|
+
lock_key, queue_ttl, acquier_id, access_strategy,
|
184
|
+
sp_conflict_status, spc_processed_timestamp
|
185
|
+
)
|
224
186
|
# SP-Conflict-Step X2: switch to dead lock logic or not
|
225
187
|
elsif sp_conflict_status == :conflict_dead_lock
|
226
188
|
inter_result = :conflict_dead_lock
|
227
189
|
spc_processed_timestamp = Time.now.to_f
|
228
190
|
|
229
|
-
|
230
|
-
logger
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
"acq_id => '#{acquier_id}' " \
|
235
|
-
"spc_status => '#{sp_conflict_status}' " \
|
236
|
-
"last_spc_ts => '#{spc_processed_timestamp}'"
|
237
|
-
end
|
238
|
-
end
|
191
|
+
LogVisitor.single_process_lock_conflict__dead_lock(
|
192
|
+
logger, log_sampled, log_lock_try,
|
193
|
+
lock_key, queue_ttl, acquier_id, access_strategy,
|
194
|
+
sp_conflict_status, spc_processed_timestamp
|
195
|
+
)
|
239
196
|
# Reached the SP-Non-Conflict Mode (NOTE):
|
240
197
|
# - in other sp-conflict cases we are in <wait_for_lock> (non-conflict) status and should
|
241
198
|
# continue to work in classic way (next lines of code):
|
@@ -246,16 +203,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
246
203
|
# Step 1: add an acquier to the lock acquirement queue
|
247
204
|
rconn.call('ZADD', lock_key_queue, 'NX', acquier_position, acquier_id)
|
248
205
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
"lock_key => '#{lock_key}' " \
|
254
|
-
"queue_ttl => #{queue_ttl} " \
|
255
|
-
"acq_id => '#{acquier_id}'"
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
206
|
+
LogVisitor.acq_added_to_queue(
|
207
|
+
logger, log_sampled, log_lock_try,
|
208
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
209
|
+
)
|
259
210
|
|
260
211
|
# Step 2.1: drop expired acquiers from the lock queue
|
261
212
|
rconn.call(
|
@@ -265,66 +216,41 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
265
216
|
RedisQueuedLocks::Resource.acquier_dead_score(queue_ttl)
|
266
217
|
)
|
267
218
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
"lock_key => '#{lock_key}' " \
|
273
|
-
"queue_ttl => #{queue_ttl} " \
|
274
|
-
"acq_id => '#{acquier_id}'"
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
219
|
+
LogVisitor.remove_expired_acqs(
|
220
|
+
logger, log_sampled, log_lock_try,
|
221
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
222
|
+
)
|
278
223
|
|
279
224
|
# Step 3: get the actual acquier waiting in the queue
|
280
225
|
waiting_acquier = Array(rconn.call('ZRANGE', lock_key_queue, '0', '0')).first
|
281
226
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
"lock_key => '#{lock_key}' " \
|
287
|
-
"queue_ttl => #{queue_ttl} " \
|
288
|
-
"acq_id => '#{acquier_id}' " \
|
289
|
-
"first_acq_id_in_queue => '#{waiting_acquier}'"
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
227
|
+
LogVisitor.get_first_from_queue(
|
228
|
+
logger, log_sampled, log_lock_try,
|
229
|
+
lock_key, queue_ttl, acquier_id, access_strategy, waiting_acquier
|
230
|
+
)
|
293
231
|
|
294
232
|
# Step PRE-4.x: check if the request time limit is reached
|
295
233
|
# (when the current try self-removes itself from queue (queue ttl has come))
|
296
234
|
if waiting_acquier == nil
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
"lock_key => '#{lock_key}' " \
|
302
|
-
"queue_ttl => #{queue_ttl} " \
|
303
|
-
"acq_id => '#{acquier_id}'"
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
235
|
+
LogVisitor.exit__queue_ttl_reached(
|
236
|
+
logger, log_sampled, log_lock_try,
|
237
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
238
|
+
)
|
307
239
|
|
308
240
|
inter_result = :dead_score_reached
|
309
|
-
|
310
|
-
|
241
|
+
# Step STRATEGY: check the stragegy and corresponding preventing factor
|
242
|
+
# Step STRATEGY (queued): check the actual acquier: is it ours? are we aready to lock?
|
243
|
+
elsif access_strategy == :queued && waiting_acquier != acquier_id
|
311
244
|
# Step ROLLBACK 1.1: our time hasn't come yet. retry!
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
"lock_key => '#{lock_key}' " \
|
318
|
-
"queue_ttl => #{queue_ttl} " \
|
319
|
-
"acq_id => '#{acquier_id}' " \
|
320
|
-
"first_acq_id_in_queue => '#{waiting_acquier}' " \
|
321
|
-
"<current_lock_data> => <<#{rconn.call('HGETALL', lock_key).to_h}>>"
|
322
|
-
end
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
245
|
+
LogVisitor.exit__no_first(
|
246
|
+
logger, log_sampled, log_lock_try,
|
247
|
+
lock_key, queue_ttl, acquier_id, access_strategy, waiting_acquier,
|
248
|
+
rconn.call('HGETALL', lock_key).to_h
|
249
|
+
)
|
326
250
|
inter_result = :acquier_is_not_first_in_queue
|
327
|
-
|
251
|
+
# Step STRAGEY: successfull (:queued OR :random)
|
252
|
+
elsif (access_strategy == :queued && waiting_acquier == acquier_id) ||
|
253
|
+
(access_strategy == :random)
|
328
254
|
# NOTE: our time has come! let's try to acquire the lock!
|
329
255
|
|
330
256
|
# Step 5: find the lock -> check if the our lock is already acquired
|
@@ -333,20 +259,12 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
333
259
|
if locked_by_acquier
|
334
260
|
# Step ROLLBACK 2: required lock is stil acquired. retry!
|
335
261
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
"acq_id => '#{acquier_id}' " \
|
343
|
-
"first_acq_id_in_queue => '#{waiting_acquier}' " \
|
344
|
-
"locked_by_acq_id => '#{locked_by_acquier}' " \
|
345
|
-
"<current_lock_data> => <<#{rconn.call('HGETALL', lock_key).to_h}>>"
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
262
|
+
LogVisitor.exit__lock_still_obtained(
|
263
|
+
logger, log_sampled, log_lock_try,
|
264
|
+
lock_key, queue_ttl, acquier_id, access_strategy,
|
265
|
+
waiting_acquier, locked_by_acquier,
|
266
|
+
rconn.call('HGETALL', lock_key).to_h
|
267
|
+
)
|
350
268
|
inter_result = :lock_is_still_acquired
|
351
269
|
else
|
352
270
|
# NOTE: required lock is free and ready to be acquired! acquire!
|
@@ -367,16 +285,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
367
285
|
# Step 6.3: set the lock expiration time in order to prevent "infinite locks"
|
368
286
|
transact.call('PEXPIRE', lock_key, ttl) # NOTE: in milliseconds
|
369
287
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
"lock_key => '#{lock_key}' " \
|
375
|
-
"queue_ttl => #{queue_ttl} " \
|
376
|
-
"acq_id => '#{acquier_id}'"
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
288
|
+
LogVisitor.obtain__free_to_acquire(
|
289
|
+
logger, log_sampled, log_lock_try,
|
290
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
291
|
+
)
|
380
292
|
end
|
381
293
|
end
|
382
294
|
end
|
@@ -479,42 +391,5 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
479
391
|
# rubocop:enable Lint/DuplicateBranch
|
480
392
|
end
|
481
393
|
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
482
|
-
|
483
|
-
# @param redis [RedisClient]
|
484
|
-
# @param logger [::Logger,#debug]
|
485
|
-
# @param lock_key [String]
|
486
|
-
# @param lock_key_queue [String]
|
487
|
-
# @param queue_ttl [Integer]
|
488
|
-
# @param acquier_id [String]
|
489
|
-
# @param log_sampled [Boolean]
|
490
|
-
# @param instr_sampled [Boolean]
|
491
|
-
# @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Any }
|
492
|
-
#
|
493
|
-
# @api private
|
494
|
-
# @since 1.0.0
|
495
|
-
# @version 1.6.0
|
496
|
-
def dequeue_from_lock_queue(
|
497
|
-
redis,
|
498
|
-
logger,
|
499
|
-
lock_key,
|
500
|
-
lock_key_queue,
|
501
|
-
queue_ttl,
|
502
|
-
acquier_id,
|
503
|
-
log_sampled,
|
504
|
-
instr_sampled
|
505
|
-
)
|
506
|
-
result = redis.call('ZREM', lock_key_queue, acquier_id)
|
507
|
-
|
508
|
-
run_non_critical do
|
509
|
-
logger.debug do
|
510
|
-
"[redis_queued_locks.fail_fast_or_limits_reached_or_deadlock__dequeue] " \
|
511
|
-
"lock_key => '#{lock_key}' " \
|
512
|
-
"queue_ttl => '#{queue_ttl}' " \
|
513
|
-
"acq_id => '#{acquier_id}'"
|
514
|
-
end
|
515
|
-
end if log_sampled
|
516
|
-
|
517
|
-
RedisQueuedLocks::Data[ok: true, result: result]
|
518
|
-
end
|
519
394
|
end
|
520
395
|
# rubocop:enable Metrics/ModuleLength, Metrics/BlockNesting
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 1.7.0
|
5
|
+
module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire::LogVisitor
|
6
|
+
extend self
|
7
|
+
|
8
|
+
# @param logger [::Logger,#debug]
|
9
|
+
# @param log_sampled [Boolean]
|
10
|
+
# @param lock_key [String]
|
11
|
+
# @param queue_ttl [Integer]
|
12
|
+
# @param acquier_id [String]
|
13
|
+
# @param access_strategy [Symbol]
|
14
|
+
# @return [void]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 1.7.0
|
18
|
+
def expire_lock(
|
19
|
+
logger,
|
20
|
+
log_sampled,
|
21
|
+
lock_key,
|
22
|
+
queue_ttl,
|
23
|
+
acquier_id,
|
24
|
+
access_strategy
|
25
|
+
)
|
26
|
+
return unless log_sampled
|
27
|
+
|
28
|
+
logger.debug do
|
29
|
+
"[redis_queued_locks.expire_lock] " \
|
30
|
+
"lock_key => '#{lock_key}' " \
|
31
|
+
"queue_ttl => #{queue_ttl} " \
|
32
|
+
"acq_id => '#{acquier_id}' " \
|
33
|
+
"acs_strat => '#{access_strategy}'"
|
34
|
+
end rescue nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param logger [::Logger,#debug]
|
38
|
+
# @param log_sampled [Boolean]
|
39
|
+
# @param lock_key [String]
|
40
|
+
# @param decreased_ttl [Integer]
|
41
|
+
# @param queue_ttl [Integer]
|
42
|
+
# @param acquier_id [String]
|
43
|
+
# @param access_strategy [Symbol]
|
44
|
+
# @return [void]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
# @since 1.7.0
|
48
|
+
def decrease_lock(
|
49
|
+
logger,
|
50
|
+
log_sampled,
|
51
|
+
lock_key,
|
52
|
+
decreased_ttl,
|
53
|
+
queue_ttl,
|
54
|
+
acquier_id,
|
55
|
+
access_strategy
|
56
|
+
)
|
57
|
+
return unless log_sampled
|
58
|
+
|
59
|
+
logger.debug do
|
60
|
+
"[redis_queued_locks.decrease_lock] " \
|
61
|
+
"lock_key => '#{lock_key}' " \
|
62
|
+
"decreased_ttl => #{decreased_ttl} " \
|
63
|
+
"queue_ttl => #{queue_ttl} " \
|
64
|
+
"acq_id => '#{acquier_id}' " \
|
65
|
+
"acs_strat => '#{access_strategy}'"
|
66
|
+
end rescue nil
|
67
|
+
end
|
68
|
+
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 1.3.0
|
5
|
+
# @version 1.7.0
|
5
6
|
module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
6
|
-
|
7
|
-
extend RedisQueuedLocks::Utilities
|
7
|
+
require_relative 'yield_expire/log_visitor'
|
8
8
|
|
9
9
|
# @return [String]
|
10
10
|
#
|
@@ -19,6 +19,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
19
19
|
# @param logger [::Logger,#debug] Logger object.
|
20
20
|
# @param lock_key [String] Obtained lock key that should be expired.
|
21
21
|
# @param acquier_id [String] Acquier identifier.
|
22
|
+
# @param access_strategy [Symbol] Lock obtaining strategy.
|
22
23
|
# @param timed [Boolean] Should the lock be wrapped by Timeout with with lock's ttl
|
23
24
|
# @param ttl_shift [Float] Lock's TTL shifting. Should affect block's ttl. In millisecodns.
|
24
25
|
# @param ttl [Integer,NilClass] Lock's time to live (in ms). Nil means "without timeout".
|
@@ -34,13 +35,14 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
34
35
|
#
|
35
36
|
# @api private
|
36
37
|
# @since 1.3.0
|
37
|
-
# @version 1.
|
38
|
+
# @version 1.7.0
|
38
39
|
# rubocop:disable Metrics/MethodLength
|
39
40
|
def yield_expire(
|
40
41
|
redis,
|
41
42
|
logger,
|
42
43
|
lock_key,
|
43
44
|
acquier_id,
|
45
|
+
access_strategy,
|
44
46
|
timed,
|
45
47
|
ttl_shift,
|
46
48
|
ttl,
|
@@ -67,15 +69,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
67
69
|
end
|
68
70
|
ensure
|
69
71
|
if should_expire
|
70
|
-
|
71
|
-
logger
|
72
|
-
|
73
|
-
|
74
|
-
"queue_ttl => #{queue_ttl} " \
|
75
|
-
"acq_id => '#{acquier_id}'"
|
76
|
-
end
|
77
|
-
end if log_sampled
|
78
|
-
|
72
|
+
LogVisitor.expire_lock(
|
73
|
+
logger, log_sampled,
|
74
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
75
|
+
)
|
79
76
|
redis.call('EXPIRE', lock_key, '0')
|
80
77
|
elsif should_decrease
|
81
78
|
finish_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
|
@@ -83,16 +80,10 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
83
80
|
decreased_ttl = ttl - spent_time - RedisQueuedLocks::Resource::REDIS_TIMESHIFT_ERROR
|
84
81
|
|
85
82
|
if decreased_ttl > 0
|
86
|
-
|
87
|
-
logger
|
88
|
-
|
89
|
-
|
90
|
-
"decreased_ttl => '#{decreased_ttl} " \
|
91
|
-
"queue_ttl => #{queue_ttl} " \
|
92
|
-
"acq_id => '#{acquier_id}' " \
|
93
|
-
end
|
94
|
-
end if log_sampled
|
95
|
-
|
83
|
+
LogVisitor.decrease_lock(
|
84
|
+
logger, log_sampled,
|
85
|
+
lock_key, decreased_ttl, queue_ttl, acquier_id, access_strategy
|
86
|
+
)
|
96
87
|
# NOTE:# NOTE: EVAL signature -> <lua script>, (number of keys), *(keys), *(arguments)
|
97
88
|
redis.call('EVAL', DECREASE_LOCK_PTTL, 1, lock_key, decreased_ttl)
|
98
89
|
# TODO: upload scripts to the redis
|