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,16 +2,20 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 1.0.0
|
5
|
+
# @version 1.7.0
|
5
6
|
# rubocop:disable Metrics/ModuleLength
|
6
7
|
# rubocop:disable Metrics/MethodLength
|
7
8
|
# rubocop:disable Metrics/ClassLength
|
8
9
|
# rubocop:disable Metrics/BlockNesting
|
9
10
|
# rubocop:disable Style/IfInsideElse
|
10
11
|
module RedisQueuedLocks::Acquier::AcquireLock
|
12
|
+
require_relative 'acquire_lock/log_visitor'
|
13
|
+
require_relative 'acquire_lock/instr_visitor'
|
11
14
|
require_relative 'acquire_lock/delay_execution'
|
12
15
|
require_relative 'acquire_lock/with_acq_timeout'
|
13
16
|
require_relative 'acquire_lock/yield_expire'
|
14
17
|
require_relative 'acquire_lock/try_to_lock'
|
18
|
+
require_relative 'acquire_lock/dequeue_from_lock_queue'
|
15
19
|
|
16
20
|
# @since 1.0.0
|
17
21
|
extend TryToLock
|
@@ -21,8 +25,8 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
21
25
|
extend YieldExpire
|
22
26
|
# @since 1.0.0
|
23
27
|
extend WithAcqTimeout
|
24
|
-
# @since 1.
|
25
|
-
extend
|
28
|
+
# @since 1.7.0
|
29
|
+
extend DequeueFromLockQueue
|
26
30
|
|
27
31
|
class << self
|
28
32
|
# @param redis [RedisClient]
|
@@ -86,6 +90,16 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
86
90
|
# - `:extendable_work_through`;
|
87
91
|
# - `:wait_for_lock`;
|
88
92
|
# - `:dead_locking`;
|
93
|
+
# @option access_strategy [Symbol]
|
94
|
+
# - The way in which the lock will be obtained;
|
95
|
+
# - By default it uses `:queued` strategy;
|
96
|
+
# - Supports following strategies:
|
97
|
+
# - `:queued` (FIFO): the classic queued behavior (default), your lock will be
|
98
|
+
# obitaned if you are first in queue and the required lock is free;
|
99
|
+
# - `:random` (RANDOM): obtain a lock without checking the positions in the queue
|
100
|
+
# (but with checking the limist, retries, timeouts and so on). if lock is
|
101
|
+
# free to obtain - it will be obtained;
|
102
|
+
# - pre-configured in `config[:default_access_strategy]`;
|
89
103
|
# @option log_sampling_enabled [Boolean]
|
90
104
|
# - enables <log sampling>: only the configured percent of RQL cases will be logged;
|
91
105
|
# - disabled by default;
|
@@ -129,7 +143,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
129
143
|
#
|
130
144
|
# @api private
|
131
145
|
# @since 1.0.0
|
132
|
-
# @version 1.
|
146
|
+
# @version 1.7.0
|
133
147
|
def acquire_lock(
|
134
148
|
redis,
|
135
149
|
lock_name,
|
@@ -153,6 +167,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
153
167
|
logger:,
|
154
168
|
log_lock_try:,
|
155
169
|
conflict_strategy:,
|
170
|
+
access_strategy:,
|
156
171
|
log_sampling_enabled:,
|
157
172
|
log_sampling_percent:,
|
158
173
|
log_sampler:,
|
@@ -236,19 +251,16 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
236
251
|
lock_key_queue,
|
237
252
|
queue_ttl,
|
238
253
|
acquier_id,
|
254
|
+
access_strategy,
|
239
255
|
log_sampled,
|
240
256
|
instr_sampled
|
241
257
|
)
|
242
258
|
end
|
243
259
|
|
244
|
-
|
245
|
-
logger
|
246
|
-
|
247
|
-
|
248
|
-
"queue_ttl => #{queue_ttl} " \
|
249
|
-
"acq_id => '#{acquier_id}'"
|
250
|
-
end
|
251
|
-
end if log_sampled
|
260
|
+
LogVisitor.start_lock_obtaining(
|
261
|
+
logger, log_sampled,
|
262
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
263
|
+
)
|
252
264
|
|
253
265
|
# Step 2: try to lock with timeout
|
254
266
|
with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
|
@@ -256,28 +268,21 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
256
268
|
|
257
269
|
# Step 2.1: cyclically try to obtain the lock
|
258
270
|
while acq_process[:should_try]
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
"acq_id => '{#{acquier_id}'"
|
265
|
-
end
|
266
|
-
end if log_sampled
|
271
|
+
|
272
|
+
LogVisitor.start_try_to_lock_cycle(
|
273
|
+
logger, log_sampled,
|
274
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
275
|
+
)
|
267
276
|
|
268
277
|
# Step 2.X: check the actual score: is it in queue ttl limit or not?
|
269
278
|
if RedisQueuedLocks::Resource.dead_score_reached?(acquier_position, queue_ttl)
|
270
279
|
# Step 2.X.X: dead score reached => re-queue the lock request with the new score;
|
271
280
|
acquier_position = RedisQueuedLocks::Resource.calc_initial_acquier_position
|
272
281
|
|
273
|
-
|
274
|
-
logger
|
275
|
-
|
276
|
-
|
277
|
-
"queue_ttl => #{queue_ttl} " \
|
278
|
-
"acq_id => '#{acquier_id}'"
|
279
|
-
end
|
280
|
-
end if log_sampled
|
282
|
+
LogVisitor.dead_score_reached__reset_acquier_position(
|
283
|
+
logger, log_sampled,
|
284
|
+
lock_key, queue_ttl, acquier_id, access_strategy
|
285
|
+
)
|
281
286
|
end
|
282
287
|
|
283
288
|
try_to_lock(
|
@@ -292,6 +297,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
292
297
|
queue_ttl,
|
293
298
|
fail_fast,
|
294
299
|
conflict_strategy,
|
300
|
+
access_strategy,
|
295
301
|
meta,
|
296
302
|
log_sampled,
|
297
303
|
instr_sampled
|
@@ -309,72 +315,38 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
309
315
|
# Step X: (instrumentation)
|
310
316
|
if acq_process[:result][:process] == :extendable_conflict_work_through
|
311
317
|
# instrumetnation: (reentrant lock with ttl extension)
|
312
|
-
|
313
|
-
logger
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
run_non_critical do
|
323
|
-
instrumenter.notify('redis_queued_locks.extendable_reentrant_lock_obtained', {
|
324
|
-
lock_key: result[:lock_key],
|
325
|
-
ttl: result[:ttl],
|
326
|
-
acq_id: result[:acq_id],
|
327
|
-
ts: result[:ts],
|
328
|
-
acq_time: acq_time,
|
329
|
-
instrument:
|
330
|
-
})
|
331
|
-
end if instr_sampled
|
318
|
+
LogVisitor.extendable_reentrant_lock_obtained(
|
319
|
+
logger, log_sampled,
|
320
|
+
result[:lock_key], queue_ttl, acquier_id, acq_time, access_strategy
|
321
|
+
)
|
322
|
+
InstrVisitor.extendable_reentrant_lock_obtained(
|
323
|
+
instrumenter, instr_sampled,
|
324
|
+
result[:lock_key], result[:ttl], result[:acq_id], result[:ts], acq_time,
|
325
|
+
instrument
|
326
|
+
)
|
332
327
|
elsif acq_process[:result][:process] == :conflict_work_through
|
333
328
|
# instrumetnation: (reentrant lock without ttl extension)
|
334
|
-
|
335
|
-
logger
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
run_non_critical do
|
345
|
-
instrumenter.notify('redis_queued_locks.reentrant_lock_obtained', {
|
346
|
-
lock_key: result[:lock_key],
|
347
|
-
ttl: result[:ttl],
|
348
|
-
acq_id: result[:acq_id],
|
349
|
-
ts: result[:ts],
|
350
|
-
acq_time: acq_time,
|
351
|
-
instrument:
|
352
|
-
})
|
353
|
-
end if instr_sampled
|
329
|
+
LogVisitor.reentrant_lock_obtained(
|
330
|
+
logger, log_sampled,
|
331
|
+
result[:lock_key], queue_ttl, acquier_id, acq_time, access_strategy
|
332
|
+
)
|
333
|
+
InstrVisitor.reentrant_lock_obtained(
|
334
|
+
instrumenter, instr_sampled,
|
335
|
+
result[:lock_key], result[:ttl], result[:acq_id], result[:ts], acq_time,
|
336
|
+
instrument
|
337
|
+
)
|
354
338
|
else
|
355
339
|
# instrumentation: (classic lock obtain)
|
356
340
|
# NOTE: classic is: acq_process[:result][:process] == :lock_obtaining
|
357
|
-
|
358
|
-
logger
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
# Step X (instrumentation): lock obtained
|
368
|
-
run_non_critical do
|
369
|
-
instrumenter.notify('redis_queued_locks.lock_obtained', {
|
370
|
-
lock_key: result[:lock_key],
|
371
|
-
ttl: result[:ttl],
|
372
|
-
acq_id: result[:acq_id],
|
373
|
-
ts: result[:ts],
|
374
|
-
acq_time: acq_time,
|
375
|
-
instrument:
|
376
|
-
})
|
377
|
-
end if instr_sampled
|
341
|
+
LogVisitor.lock_obtained(
|
342
|
+
logger, log_sampled,
|
343
|
+
result[:lock_key], queue_ttl, acquier_id, acq_time, access_strategy
|
344
|
+
)
|
345
|
+
InstrVisitor.lock_obtained(
|
346
|
+
instrumenter, instr_sampled,
|
347
|
+
result[:lock_key], result[:ttl], result[:acq_id], result[:ts], acq_time,
|
348
|
+
instrument
|
349
|
+
)
|
378
350
|
end
|
379
351
|
|
380
352
|
# Step 2.1.a: successfully acquired => build the result
|
@@ -478,6 +450,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
478
450
|
logger,
|
479
451
|
lock_key,
|
480
452
|
acquier_id,
|
453
|
+
access_strategy,
|
481
454
|
timed,
|
482
455
|
ttl_shift,
|
483
456
|
ttl,
|
@@ -499,30 +472,30 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
499
472
|
if acq_process[:result][:process] == :extendable_conflict_work_through ||
|
500
473
|
acq_process[:result][:process] == :conflict_work_through
|
501
474
|
# Step X (instrumentation): reentrant_lock_hold_completes
|
502
|
-
|
503
|
-
instrumenter
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
475
|
+
InstrVisitor.reentrant_lock_hold_completes(
|
476
|
+
instrumenter,
|
477
|
+
instr_sampled,
|
478
|
+
acq_process[:lock_info][:lock_key],
|
479
|
+
acq_process[:lock_info][:ttl],
|
480
|
+
acq_process[:lock_info][:acq_id],
|
481
|
+
acq_process[:lock_info][:ts],
|
482
|
+
acq_process[:acq_time],
|
483
|
+
acq_process[:hold_time],
|
484
|
+
instrument
|
485
|
+
)
|
513
486
|
else
|
514
487
|
# Step X (instrumentation): lock_hold_and_release
|
515
|
-
|
516
|
-
instrumenter
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
488
|
+
InstrVisitor.lock_hold_and_release(
|
489
|
+
instrumenter,
|
490
|
+
instr_sampled,
|
491
|
+
acq_process[:lock_info][:lock_key],
|
492
|
+
acq_process[:lock_info][:ttl],
|
493
|
+
acq_process[:lock_info][:acq_id],
|
494
|
+
acq_process[:lock_info][:ts],
|
495
|
+
acq_process[:lock_info][:lock_key],
|
496
|
+
acq_process[:acq_time],
|
497
|
+
instrument
|
498
|
+
)
|
526
499
|
end
|
527
500
|
end
|
528
501
|
else
|
@@ -23,6 +23,7 @@ class RedisQueuedLocks::Client
|
|
23
23
|
setting :dead_request_ttl, (1 * 24 * 60 * 60 * 1000) # NOTE: 1 day in milliseconds
|
24
24
|
setting :is_timed_by_default, false
|
25
25
|
setting :default_conflict_strategy, :wait_for_lock
|
26
|
+
setting :default_access_strategy, :queued
|
26
27
|
setting :log_sampling_enabled, false
|
27
28
|
setting :log_sampling_percent, 15
|
28
29
|
setting :log_sampler, RedisQueuedLocks::Logging::Sampler
|
@@ -57,6 +58,12 @@ class RedisQueuedLocks::Client
|
|
57
58
|
val == :dead_locking
|
58
59
|
# rubocop:enable Layout/MultilineOperationIndentation
|
59
60
|
end
|
61
|
+
validate('default_access_strategy') do |val|
|
62
|
+
# rubocop:disable Layout/MultilineOperationIndentation
|
63
|
+
val == :queued ||
|
64
|
+
val == :random
|
65
|
+
# rubocop:enable Layout/MultilineOperationIndentation
|
66
|
+
end
|
60
67
|
end
|
61
68
|
|
62
69
|
# @return [RedisClient]
|
@@ -126,6 +133,16 @@ class RedisQueuedLocks::Client
|
|
126
133
|
# - `:wait_for_lock` - (default) - work in classic way
|
127
134
|
# (with timeouts, retry delays, retry limits, etc - in classic way :));
|
128
135
|
# - `:dead_locking` - fail with deadlock exception;
|
136
|
+
# @option access_strategy [Symbol]
|
137
|
+
# - The way in which the lock will be obtained;
|
138
|
+
# - By default it uses `:queued` strategy;
|
139
|
+
# - Supports following strategies:
|
140
|
+
# - `:queued` (FIFO): the classic queued behavior (default), your lock will be
|
141
|
+
# obitaned if you are first in queue and the required lock is free;
|
142
|
+
# - `:random` (RANDOM): obtain a lock without checking the positions in the queue
|
143
|
+
# (but with checking the limist, retries, timeouts and so on). if lock is
|
144
|
+
# free to obtain - it will be obtained;
|
145
|
+
# - pre-configured in `config[:default_access_strategy]`;
|
129
146
|
# @option meta [NilClass,Hash<String|Symbol,Any>]
|
130
147
|
# - A custom metadata wich will be passed to the lock data in addition to the existing data;
|
131
148
|
# - Metadata can not contain reserved lock data keys;
|
@@ -189,7 +206,7 @@ class RedisQueuedLocks::Client
|
|
189
206
|
#
|
190
207
|
# @api public
|
191
208
|
# @since 1.0.0
|
192
|
-
# @version 1.
|
209
|
+
# @version 1.7.0
|
193
210
|
# rubocop:disable Metrics/MethodLength
|
194
211
|
def lock(
|
195
212
|
lock_name,
|
@@ -203,6 +220,7 @@ class RedisQueuedLocks::Client
|
|
203
220
|
raise_errors: false,
|
204
221
|
fail_fast: false,
|
205
222
|
conflict_strategy: config[:default_conflict_strategy],
|
223
|
+
access_strategy: config[:default_access_strategy],
|
206
224
|
identity: uniq_identity,
|
207
225
|
meta: nil,
|
208
226
|
logger: config[:logger],
|
@@ -236,6 +254,7 @@ class RedisQueuedLocks::Client
|
|
236
254
|
identity:,
|
237
255
|
fail_fast:,
|
238
256
|
conflict_strategy:,
|
257
|
+
access_strategy:,
|
239
258
|
meta:,
|
240
259
|
logger:,
|
241
260
|
log_lock_try:,
|
@@ -255,7 +274,7 @@ class RedisQueuedLocks::Client
|
|
255
274
|
#
|
256
275
|
# @api public
|
257
276
|
# @since 1.0.0
|
258
|
-
# @version 1.
|
277
|
+
# @version 1.7.0
|
259
278
|
# rubocop:disable Metrics/MethodLength
|
260
279
|
def lock!(
|
261
280
|
lock_name,
|
@@ -268,6 +287,7 @@ class RedisQueuedLocks::Client
|
|
268
287
|
retry_jitter: config[:retry_jitter],
|
269
288
|
fail_fast: false,
|
270
289
|
conflict_strategy: config[:default_conflict_strategy],
|
290
|
+
access_strategy: config[:default_access_strategy],
|
271
291
|
identity: uniq_identity,
|
272
292
|
instrumenter: config[:instrumenter],
|
273
293
|
meta: nil,
|
@@ -300,6 +320,7 @@ class RedisQueuedLocks::Client
|
|
300
320
|
instrument:,
|
301
321
|
instrumenter:,
|
302
322
|
conflict_strategy:,
|
323
|
+
access_strategy:,
|
303
324
|
log_sampling_enabled:,
|
304
325
|
log_sampling_percent:,
|
305
326
|
log_sampler:,
|
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
data/redis_queued_locks.gemspec
CHANGED
@@ -10,9 +10,29 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ['Rustam Ibragimov']
|
11
11
|
spec.email = ['iamdaiver@gmail.com']
|
12
12
|
|
13
|
-
spec.summary
|
14
|
-
|
15
|
-
|
13
|
+
spec.summary =
|
14
|
+
'Distributed locks with "prioritized lock acquisition queue" ' \
|
15
|
+
'capabilities based on the Redis Database.'
|
16
|
+
|
17
|
+
spec.description =
|
18
|
+
'Distributed locks with "prioritized lock acquisition queue" capabilities ' \
|
19
|
+
'based on the Redis Database. ' \
|
20
|
+
# ---
|
21
|
+
'Each lock request is put into the request queue ' \
|
22
|
+
"(each lock is hosted by it's own queue separately from other queues) and processed " \
|
23
|
+
'in order of their priority (FIFO). ' \
|
24
|
+
# ---
|
25
|
+
'Each lock request lives some period of time (RTTL) ' \
|
26
|
+
'(with requeue capabilities) which guarantees the request queue will never be stacked. ' \
|
27
|
+
# ---
|
28
|
+
'In addition to the classic `queued` (FIFO) strategy RQL supports ' \
|
29
|
+
'`random` (RANDOM) lock obtaining strategy when any acquirer from the lock queue ' \
|
30
|
+
'can obtain the lock regardless the position in the queue. ' \
|
31
|
+
# ---
|
32
|
+
'Provides flexible invocation flow, parametrized limits ' \
|
33
|
+
'(lock request ttl, lock ttl, queue ttl, lock attempts limit, fast failing, etc), ' \
|
34
|
+
'logging and instrumentation.'
|
35
|
+
|
16
36
|
spec.homepage = 'https://github.com/0exp/redis_queued_locks'
|
17
37
|
spec.license = 'MIT'
|
18
38
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_queued_locks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -38,8 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.28'
|
41
|
-
description: Distributed locks with "lock acquisition queue" capabilities
|
42
|
-
the Redis Database.
|
41
|
+
description: 'Distributed locks with "prioritized lock acquisition queue" capabilities
|
42
|
+
based on the Redis Database. '
|
43
43
|
email:
|
44
44
|
- iamdaiver@gmail.com
|
45
45
|
executables: []
|
@@ -58,9 +58,15 @@ files:
|
|
58
58
|
- lib/redis_queued_locks/acquier.rb
|
59
59
|
- lib/redis_queued_locks/acquier/acquire_lock.rb
|
60
60
|
- lib/redis_queued_locks/acquier/acquire_lock/delay_execution.rb
|
61
|
+
- lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue.rb
|
62
|
+
- lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue/log_visitor.rb
|
63
|
+
- lib/redis_queued_locks/acquier/acquire_lock/instr_visitor.rb
|
64
|
+
- lib/redis_queued_locks/acquier/acquire_lock/log_visitor.rb
|
61
65
|
- lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb
|
66
|
+
- lib/redis_queued_locks/acquier/acquire_lock/try_to_lock/log_visitor.rb
|
62
67
|
- lib/redis_queued_locks/acquier/acquire_lock/with_acq_timeout.rb
|
63
68
|
- lib/redis_queued_locks/acquier/acquire_lock/yield_expire.rb
|
69
|
+
- lib/redis_queued_locks/acquier/acquire_lock/yield_expire/log_visitor.rb
|
64
70
|
- lib/redis_queued_locks/acquier/clear_dead_requests.rb
|
65
71
|
- lib/redis_queued_locks/acquier/extend_lock_ttl.rb
|
66
72
|
- lib/redis_queued_locks/acquier/is_locked.rb
|
@@ -87,6 +93,7 @@ files:
|
|
87
93
|
- lib/redis_queued_locks/resource.rb
|
88
94
|
- lib/redis_queued_locks/utilities.rb
|
89
95
|
- lib/redis_queued_locks/version.rb
|
96
|
+
- lib/redis_queued_locks/watcher.rb
|
90
97
|
- redis_queued_locks.gemspec
|
91
98
|
homepage: https://github.com/0exp/redis_queued_locks
|
92
99
|
licenses:
|
@@ -113,5 +120,6 @@ requirements: []
|
|
113
120
|
rubygems_version: 3.3.7
|
114
121
|
signing_key:
|
115
122
|
specification_version: 4
|
116
|
-
summary:
|
123
|
+
summary: Distributed locks with "prioritized lock acquisition queue" capabilities
|
124
|
+
based on the Redis Database.
|
117
125
|
test_files: []
|