redis_queued_locks 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +93 -5
- data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb +8 -4
- data/lib/redis_queued_locks/acquier/acquire_lock/yield_expire.rb +7 -2
- data/lib/redis_queued_locks/acquier/acquire_lock.rb +51 -19
- data/lib/redis_queued_locks/acquier/clear_dead_requests.rb +8 -1
- data/lib/redis_queued_locks/acquier/extend_lock_ttl.rb +12 -2
- data/lib/redis_queued_locks/acquier/release_all_locks.rb +44 -8
- data/lib/redis_queued_locks/acquier/release_lock.rb +46 -14
- data/lib/redis_queued_locks/client.rb +107 -31
- data/lib/redis_queued_locks/instrument/sampler.rb +27 -0
- data/lib/redis_queued_locks/instrument.rb +47 -0
- data/lib/redis_queued_locks/logging/sampler.rb +10 -3
- data/lib/redis_queued_locks/logging.rb +1 -0
- data/lib/redis_queued_locks/version.rb +2 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd9e0ee49d4c08d6ba572a825da792468926b2f676e872a2337b1ce2eff60836
|
4
|
+
data.tar.gz: ae635ac450f966539581c4b5a53098b92ba29562bb0641049571ca0ceb1461e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b678b3fbccd5273d17d07120c144b0eb1c6be32db73ff1aa2f9fb19f485d30499645f3c4592fad0cb4cdeab1ebcd37f437b62740e01a46dce999eaaa2814f146
|
7
|
+
data.tar.gz: b8cb79c79767cd1d3b831992454c84c8399f6bf7ac313b8a2d0a7527711f555cb2196a172ae435103df2fc4c3e483b0a5b35775fba4baee7b7bad6234103cb0a
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.6.0] - 2024-05-25
|
4
|
+
### Added
|
5
|
+
- New Feature: **Instrumentation Sampling** - configurable instrumentation sampling based on `weight` algorithm (where the weight is a percentage of RQL cases that should be logged);
|
6
|
+
- Missing instrumenter customization in public `RedisQueuedLocks::Client` methods;
|
7
|
+
- Documentation updates;
|
8
|
+
|
3
9
|
## [1.5.0] - 2024-05-23
|
4
10
|
### Added
|
5
|
-
- New Feature: **Log sampling** - configurable log sampling based on `weight` algorithm (where the weight is a percentage);
|
11
|
+
- New Feature: **Log sampling** - configurable log sampling based on `weight` algorithm (where the weight is a percentage of RQL cases that should be logged);
|
6
12
|
|
7
13
|
## [1.4.0] - 2024-05-13
|
8
14
|
### Added
|
data/README.md
CHANGED
@@ -253,6 +253,27 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
|
|
253
253
|
# - you can provide your own log sampler with bettter algorithm that should realize
|
254
254
|
# `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Logging::Sampler` for example);
|
255
255
|
config.log_sampler = RedisQueuedLocks::Logging::Sampler
|
256
|
+
|
257
|
+
# (default: false)
|
258
|
+
# - enables <instrumentaion sampling>: only the configured percent of RQL cases will be instrumented;
|
259
|
+
# - disabled by default;
|
260
|
+
# - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
|
261
|
+
config.instr_sampling_enabled = false
|
262
|
+
|
263
|
+
# (default: 15)
|
264
|
+
# - the percent of cases that should be instrumented;
|
265
|
+
# - take an effect when <config.instr_sampling_enalbed> is true;
|
266
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
|
267
|
+
config.instr_sampling_percent = 15
|
268
|
+
|
269
|
+
# (default: RedisQueuedLocks::Instrument::Sampler)
|
270
|
+
# - percent-based log sampler that decides should be RQL case instrumented or not;
|
271
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampling_percent> configs;
|
272
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
|
273
|
+
# method so the algorithm error is ~(0%..13%);
|
274
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
275
|
+
# `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
276
|
+
config.instr_sampler = RedisQueuedLocks::Instrument::Sampler
|
256
277
|
end
|
257
278
|
```
|
258
279
|
|
@@ -309,11 +330,15 @@ def lock(
|
|
309
330
|
identity: uniq_identity, # (attr_accessor) calculated during client instantiation via config[:uniq_identifier] proc;
|
310
331
|
meta: nil,
|
311
332
|
instrument: nil,
|
333
|
+
instrumenter: config[:instrumenter],
|
312
334
|
logger: config[:logger],
|
313
335
|
log_lock_try: config[:log_lock_try],
|
314
336
|
log_sampling_enabled: config[:log_sampling_enabled],
|
315
337
|
log_sampling_percent: config[:log_sampling_percent],
|
316
338
|
log_sampler: config[:log_sampler],
|
339
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
340
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
341
|
+
instr_sampler: config[:instr_sampler],
|
317
342
|
&block
|
318
343
|
)
|
319
344
|
```
|
@@ -346,6 +371,9 @@ def lock(
|
|
346
371
|
- See RedisQueuedLocks::Instrument::ActiveSupport for example;
|
347
372
|
- See [Instrumentation](#instrumentation) section of docs;
|
348
373
|
- pre-configured in `config[:isntrumenter]` with void notifier (`RedisQueuedLocks::Instrumenter::VoidNotifier`);
|
374
|
+
- `instrument` - (optional) `[NilClass,Any]`
|
375
|
+
- Custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
|
376
|
+
- `nil` by default (means "no custom instrumentation data");
|
349
377
|
- `raise_errors` - (optional) `[Boolean]`
|
350
378
|
- Raise errors on library-related limits (such as timeout or retry count limit) and on lock conflicts (such as same-process dead locks);
|
351
379
|
- `false` by default;
|
@@ -377,9 +405,6 @@ def lock(
|
|
377
405
|
- A custom metadata wich will be passed to the lock data in addition to the existing data;
|
378
406
|
- Custom metadata can not contain reserved lock data keys (such as `lock_key`, `acq_id`, `ts`, `ini_ttl`, `rem_ttl`);
|
379
407
|
- `nil` by default (means "no metadata");
|
380
|
-
- `instrument` - (optional) `[NilClass,Any]`
|
381
|
-
- Custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
|
382
|
-
- `nil` by default (means "no custom instrumentation data");
|
383
408
|
- `logger` - (optional) `[::Logger,#debug]`
|
384
409
|
- Logger object used for loggin internal mutation oeprations and opertioan results / process progress;
|
385
410
|
- pre-configured in `config[:logger]` with void logger `RedisQueuedLocks::Logging::VoidLogger`;
|
@@ -405,6 +430,24 @@ def lock(
|
|
405
430
|
- you can provide your own log sampler with bettter algorithm that should realize
|
406
431
|
`sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Logging::Sampler` for example);
|
407
432
|
- pre-configured in `config[:log_sampler]`;
|
433
|
+
- `instr_sampling_enabled` - (optional) `[Boolean]`
|
434
|
+
- enables **instrumentaion sampling**: only the configured percent of RQL cases will be instrumented;
|
435
|
+
- disabled by default;
|
436
|
+
- works in tandem with `instr_sampling_percent` and `instr_sampler` options;
|
437
|
+
- pre-configured in `config[:instr_sampling_enabled]`;
|
438
|
+
- `instr_sampling_percent` - (optional) `[Integer]`
|
439
|
+
- the percent of cases that should be instrumented;
|
440
|
+
- take an effect when `instr_sampling_enalbed` is true;
|
441
|
+
- works in tandem with `instr_sampling_enabled` and `instr_sampler` options;
|
442
|
+
- pre-configured in `config[:instr_sampling_percent]`;
|
443
|
+
- `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
|
444
|
+
- percent-based log sampler that decides should be RQL case instrumented or not;
|
445
|
+
- works in tandem with `instr_sampling_enabled` and `instr_sampling_percent` options;
|
446
|
+
- based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
|
447
|
+
method so the algorithm error is ~(0%..13%);
|
448
|
+
- you can provide your own log sampler with bettter algorithm that should realize
|
449
|
+
`sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
450
|
+
- pre-configured in `config[:instr_sampler]`;
|
408
451
|
- `block` - (optional) `[Block]`
|
409
452
|
- A block of code that should be executed after the successfully acquired lock.
|
410
453
|
- If block is **passed** the obtained lock will be released after the block execution or it's ttl (what will happen first);
|
@@ -558,7 +601,7 @@ rql.lock("my_lock", queue_ttl: 5, timeout: 10_000, retry_count: nil)
|
|
558
601
|
|
559
602
|
# lock queue: =>
|
560
603
|
[
|
561
|
-
"rql:acq:123/456/567/676/374dd74324",
|
604
|
+
"rql:acq:123/456/567/676/374dd74324",
|
562
605
|
"rql:acq:123/456/567/677/374dd74322", # <- long living lock
|
563
606
|
"rql:acq:123/456/567/679/374dd74321",
|
564
607
|
"rql:acq:123/456/567/683/374dd74322", # <== we are here
|
@@ -613,10 +656,14 @@ def lock!(
|
|
613
656
|
logger: config[:logger],
|
614
657
|
log_lock_try: config[:log_lock_try],
|
615
658
|
instrument: nil,
|
659
|
+
instrumenter: config[:instrumenter],
|
616
660
|
conflict_strategy: config[:default_conflict_strategy],
|
617
661
|
log_sampling_enabled: config[:log_sampling_enabled],
|
618
662
|
log_sampling_percent: config[:log_sampling_percent],
|
619
663
|
log_sampler: config[:log_sampler],
|
664
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
665
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
666
|
+
instr_sampler: config[:instr_sampler],
|
620
667
|
&block
|
621
668
|
)
|
622
669
|
```
|
@@ -797,6 +844,15 @@ rql.queued?("your_lock_name") # => true/false
|
|
797
844
|
- `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
|
798
845
|
- **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
|
799
846
|
- pre-configured in `config[:log_sampler]`;
|
847
|
+
- `:instr_sampling_enabled` - (optional) `[Boolean]`
|
848
|
+
- enables **instrumentaion sampling**;
|
849
|
+
- pre-configured in `config[:instr_sampling_enabled]`;
|
850
|
+
- `instr_sampling_percent` - (optional) `[Integer]`
|
851
|
+
- the percent of cases that should be instrumented;
|
852
|
+
- pre-configured in `config[:instr_sampling_percent]`;
|
853
|
+
- `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
|
854
|
+
- percent-based log sampler that decides should be RQL case instrumented or not;
|
855
|
+
- pre-configured in `config[:instr_sampler]`;
|
800
856
|
- if you try to unlock non-existent lock you will receive `ok: true` result with operation timings
|
801
857
|
and `:nothing_to_release` result factor inside;
|
802
858
|
|
@@ -856,6 +912,15 @@ rql.unlock("your_lock_name")
|
|
856
912
|
- `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
|
857
913
|
- **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
|
858
914
|
- pre-configured in `config[:log_sampler]`;
|
915
|
+
- `:instr_sampling_enabled` - (optional) `[Boolean]`
|
916
|
+
- enables **instrumentaion sampling**;
|
917
|
+
- pre-configured in `config[:instr_sampling_enabled]`;
|
918
|
+
- `instr_sampling_percent` - (optional) `[Integer]`
|
919
|
+
- the percent of cases that should be instrumented;
|
920
|
+
- pre-configured in `config[:instr_sampling_percent]`;
|
921
|
+
- `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
|
922
|
+
- percent-based log sampler that decides should be RQL case instrumented or not;
|
923
|
+
- pre-configured in `config[:instr_sampler]`;
|
859
924
|
- returns:
|
860
925
|
- `[Hash<Symbol,Numeric>]` - Format: `{ ok: true, result: Hash<Symbol,Numeric> }`;
|
861
926
|
- result data:
|
@@ -888,6 +953,12 @@ rql.clear_locks
|
|
888
953
|
- the lock name which ttl should be extended;
|
889
954
|
- `milliseconds` - (required) `[Integer]`
|
890
955
|
- how many milliseconds should be added to the lock's TTL;
|
956
|
+
- `:instrumenter` - (optional) `[#notify]`
|
957
|
+
- custom instrumenter object;
|
958
|
+
- pre-configured in `config[:instrumetner]`;
|
959
|
+
- `:instrument` - (optional) `[NilClass,Any]`;
|
960
|
+
- custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
|
961
|
+
- `nil` by default (no additional data);
|
891
962
|
- `:logger` - (optional) `[::Logger,#debug]`
|
892
963
|
- custom logger object;
|
893
964
|
- pre-configured in `config[:logger]`;
|
@@ -900,6 +971,15 @@ rql.clear_locks
|
|
900
971
|
- `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
|
901
972
|
- **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
|
902
973
|
- pre-configured in `config[:log_sampler]`;
|
974
|
+
- `:instr_sampling_enabled` - (optional) `[Boolean]`
|
975
|
+
- enables **instrumentaion sampling**;
|
976
|
+
- pre-configured in `config[:instr_sampling_enabled]`;
|
977
|
+
- `instr_sampling_percent` - (optional) `[Integer]`
|
978
|
+
- the percent of cases that should be instrumented;
|
979
|
+
- pre-configured in `config[:instr_sampling_percent]`;
|
980
|
+
- `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
|
981
|
+
- percent-based log sampler that decides should be RQL case instrumented or not;
|
982
|
+
- pre-configured in `config[:instr_sampler]`;
|
903
983
|
- returns `{ ok: true, result: :ttl_extended }` when ttl is extended;
|
904
984
|
- returns `{ ok: false, result: :async_expire_or_no_lock }` when a lock not found or a lock is already expired during
|
905
985
|
some steps of invocation (see **Important** section below);
|
@@ -1137,6 +1217,15 @@ Accepts:
|
|
1137
1217
|
- `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
|
1138
1218
|
- **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
|
1139
1219
|
- pre-configured in `config[:log_sampler]`;
|
1220
|
+
- `:instr_sampling_enabled` - (optional) `[Boolean]`
|
1221
|
+
- enables **instrumentaion sampling**;
|
1222
|
+
- pre-configured in `config[:instr_sampling_enabled]`;
|
1223
|
+
- `instr_sampling_percent` - (optional) `[Integer]`
|
1224
|
+
- the percent of cases that should be instrumented;
|
1225
|
+
- pre-configured in `config[:instr_sampling_percent]`;
|
1226
|
+
- `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
|
1227
|
+
- percent-based log sampler that decides should be RQL case instrumented or not;
|
1228
|
+
- pre-configured in `config[:instr_sampler]`;
|
1140
1229
|
|
1141
1230
|
Returns: `{ ok: true, processed_queues: Set<String> }` returns the list of processed lock queues;
|
1142
1231
|
|
@@ -1335,7 +1424,6 @@ Detalized event semantics and payload structure:
|
|
1335
1424
|
<sup>\[[back to top](#table-of-contents)\]</sup>
|
1336
1425
|
|
1337
1426
|
- **Major**:
|
1338
|
-
- precent-based instrumentation sampling (instrument the concrete % of cases via "sampling" strategy);
|
1339
1427
|
- support for Random Access strategy (non-queued behavior);
|
1340
1428
|
- lock request prioritization;
|
1341
1429
|
- **strict redlock algorithm support** (support for many `RedisClient` instances);
|
@@ -29,11 +29,12 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
29
29
|
# @param conflict_strategy [Symbol]
|
30
30
|
# @param meta [NilClass,Hash<String|Symbol,Any>]
|
31
31
|
# @param log_sampled [Boolean]
|
32
|
+
# @param instr_sampled [Boolean]
|
32
33
|
# @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Symbol|Hash<Symbol,Any> }
|
33
34
|
#
|
34
35
|
# @api private
|
35
36
|
# @since 1.0.0
|
36
|
-
# @version 1.
|
37
|
+
# @version 1.6.0
|
37
38
|
# rubocop:disable Metrics/MethodLength
|
38
39
|
def try_to_lock(
|
39
40
|
redis,
|
@@ -48,7 +49,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
48
49
|
fail_fast,
|
49
50
|
conflict_strategy,
|
50
51
|
meta,
|
51
|
-
log_sampled
|
52
|
+
log_sampled,
|
53
|
+
instr_sampled
|
52
54
|
)
|
53
55
|
# Step X: intermediate invocation results
|
54
56
|
inter_result = nil
|
@@ -485,11 +487,12 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
485
487
|
# @param queue_ttl [Integer]
|
486
488
|
# @param acquier_id [String]
|
487
489
|
# @param log_sampled [Boolean]
|
490
|
+
# @param instr_sampled [Boolean]
|
488
491
|
# @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Any }
|
489
492
|
#
|
490
493
|
# @api private
|
491
494
|
# @since 1.0.0
|
492
|
-
# @version 1.
|
495
|
+
# @version 1.6.0
|
493
496
|
def dequeue_from_lock_queue(
|
494
497
|
redis,
|
495
498
|
logger,
|
@@ -497,7 +500,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
497
500
|
lock_key_queue,
|
498
501
|
queue_ttl,
|
499
502
|
acquier_id,
|
500
|
-
log_sampled
|
503
|
+
log_sampled,
|
504
|
+
instr_sampled
|
501
505
|
)
|
502
506
|
result = redis.call('ZREM', lock_key_queue, acquier_id)
|
503
507
|
|
@@ -24,7 +24,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
24
24
|
# @param ttl [Integer,NilClass] Lock's time to live (in ms). Nil means "without timeout".
|
25
25
|
# @param queue_ttl [Integer] Lock request lifetime.
|
26
26
|
# @param block [Block] Custom logic that should be invoked unter the obtained lock.
|
27
|
-
# @param log_sampled [Boolean] Should the logic be logged or not
|
27
|
+
# @param log_sampled [Boolean] Should the logic be logged or not.
|
28
|
+
# @param instr_sampled [Boolean] Should the logic be instrumented or not.
|
28
29
|
# @param should_expire [Boolean] Should the lock be expired after the block invocation.
|
29
30
|
# @param should_decrease [Boolean]
|
30
31
|
# - Should decrease the lock TTL after the lock invocation;
|
@@ -33,7 +34,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
33
34
|
#
|
34
35
|
# @api private
|
35
36
|
# @since 1.3.0
|
36
|
-
# @version 1.
|
37
|
+
# @version 1.6.0
|
37
38
|
# rubocop:disable Metrics/MethodLength
|
38
39
|
def yield_expire(
|
39
40
|
redis,
|
@@ -45,6 +46,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
45
46
|
ttl,
|
46
47
|
queue_ttl,
|
47
48
|
log_sampled,
|
49
|
+
instr_sampled,
|
48
50
|
should_expire,
|
49
51
|
should_decrease,
|
50
52
|
&block
|
@@ -73,11 +75,13 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
73
75
|
"acq_id => '#{acquier_id}'"
|
74
76
|
end
|
75
77
|
end if log_sampled
|
78
|
+
|
76
79
|
redis.call('EXPIRE', lock_key, '0')
|
77
80
|
elsif should_decrease
|
78
81
|
finish_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
|
79
82
|
spent_time = (finish_time - initial_time)
|
80
83
|
decreased_ttl = ttl - spent_time - RedisQueuedLocks::Resource::REDIS_TIMESHIFT_ERROR
|
84
|
+
|
81
85
|
if decreased_ttl > 0
|
82
86
|
run_non_critical do
|
83
87
|
logger.debug do
|
@@ -88,6 +92,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
|
|
88
92
|
"acq_id => '#{acquier_id}' " \
|
89
93
|
end
|
90
94
|
end if log_sampled
|
95
|
+
|
91
96
|
# NOTE:# NOTE: EVAL signature -> <lua script>, (number of keys), *(keys), *(arguments)
|
92
97
|
redis.call('EVAL', DECREASE_LOCK_PTTL, 1, lock_key, decreased_ttl)
|
93
98
|
# TODO: upload scripts to the redis
|
@@ -87,19 +87,40 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
87
87
|
# - `:wait_for_lock`;
|
88
88
|
# - `:dead_locking`;
|
89
89
|
# @option log_sampling_enabled [Boolean]
|
90
|
-
# -
|
91
|
-
# -
|
92
|
-
#
|
93
|
-
# - You can provide your own sampler via config[:log_sampler] config and :sampler option
|
94
|
-
# (see `RedisQueuedLocks::Logging::Sampler` for examples);
|
95
|
-
# - The spread of guaranteed percent is approximately +13% (rand method spread);
|
96
|
-
# - Take an effect when <log_sampling_enabled> parameter has <true> value
|
97
|
-
# (when log sampling is enabled);
|
90
|
+
# - enables <log sampling>: only the configured percent of RQL cases will be logged;
|
91
|
+
# - disabled by default;
|
92
|
+
# - works in tandem with <config.log_sampling_percent and <log.sampler>;
|
98
93
|
# @option log_sampling_percent [Integer]
|
99
|
-
# -
|
100
|
-
# -
|
101
|
-
#
|
94
|
+
# - the percent of cases that should be logged;
|
95
|
+
# - take an effect when <config.log_sampling_enalbed> is true;
|
96
|
+
# - works in tandem with <config.log_sampling_enabled> and <config.log_sampler> configs;
|
102
97
|
# @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
98
|
+
# - percent-based log sampler that decides should be RQL case logged or not;
|
99
|
+
# - works in tandem with <config.log_sampling_enabled> and
|
100
|
+
# <config.log_sampling_percent> configs;
|
101
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
102
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
103
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
104
|
+
# `sampling_happened?(percent) => boolean` interface
|
105
|
+
# (see `RedisQueuedLocks::Logging::Sampler` for example);
|
106
|
+
# @option instr_sampling_enabled [Boolean]
|
107
|
+
# - enables <instrumentaion sampling>: only the configured percent
|
108
|
+
# of RQL cases will be instrumented;
|
109
|
+
# - disabled by default;
|
110
|
+
# - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
|
111
|
+
# @option instr_sampling_percent [Integer]
|
112
|
+
# - the percent of cases that should be instrumented;
|
113
|
+
# - take an effect when <config.instr_sampling_enalbed> is true;
|
114
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
|
115
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
116
|
+
# - percent-based log sampler that decides should be RQL case instrumented or not;
|
117
|
+
# - works in tandem with <config.instr_sampling_enabled> and
|
118
|
+
# <config.instr_sampling_percent> configs;
|
119
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
120
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
121
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
122
|
+
# `sampling_happened?(percent) => boolean` interface
|
123
|
+
# (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
103
124
|
# @param [Block]
|
104
125
|
# A block of code that should be executed after the successfully acquired lock.
|
105
126
|
# @return [RedisQueuedLocks::Data,Hash<Symbol,Any>,yield]
|
@@ -108,7 +129,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
108
129
|
#
|
109
130
|
# @api private
|
110
131
|
# @since 1.0.0
|
111
|
-
# @version 1.
|
132
|
+
# @version 1.6.0
|
112
133
|
def acquire_lock(
|
113
134
|
redis,
|
114
135
|
lock_name,
|
@@ -135,6 +156,9 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
135
156
|
log_sampling_enabled:,
|
136
157
|
log_sampling_percent:,
|
137
158
|
log_sampler:,
|
159
|
+
instr_sampling_enabled:,
|
160
|
+
instr_sampling_percent:,
|
161
|
+
instr_sampler:,
|
138
162
|
&block
|
139
163
|
)
|
140
164
|
# Step 0: Prevent argument type incompatabilities
|
@@ -187,6 +211,11 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
187
211
|
log_sampling_percent,
|
188
212
|
log_sampler
|
189
213
|
)
|
214
|
+
instr_sampled = RedisQueuedLocks::Instrument.should_instrument?(
|
215
|
+
instr_sampling_enabled,
|
216
|
+
instr_sampling_percent,
|
217
|
+
instr_sampler
|
218
|
+
)
|
190
219
|
|
191
220
|
# Step X: intermediate result observer
|
192
221
|
acq_process = {
|
@@ -207,7 +236,8 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
207
236
|
lock_key_queue,
|
208
237
|
queue_ttl,
|
209
238
|
acquier_id,
|
210
|
-
log_sampled
|
239
|
+
log_sampled,
|
240
|
+
instr_sampled
|
211
241
|
)
|
212
242
|
end
|
213
243
|
|
@@ -263,7 +293,8 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
263
293
|
fail_fast,
|
264
294
|
conflict_strategy,
|
265
295
|
meta,
|
266
|
-
log_sampled
|
296
|
+
log_sampled,
|
297
|
+
instr_sampled
|
267
298
|
) => { ok:, result: }
|
268
299
|
|
269
300
|
acq_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :microsecond)
|
@@ -297,7 +328,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
297
328
|
acq_time: acq_time,
|
298
329
|
instrument:
|
299
330
|
})
|
300
|
-
end
|
331
|
+
end if instr_sampled
|
301
332
|
elsif acq_process[:result][:process] == :conflict_work_through
|
302
333
|
# instrumetnation: (reentrant lock without ttl extension)
|
303
334
|
run_non_critical do
|
@@ -319,7 +350,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
319
350
|
acq_time: acq_time,
|
320
351
|
instrument:
|
321
352
|
})
|
322
|
-
end
|
353
|
+
end if instr_sampled
|
323
354
|
else
|
324
355
|
# instrumentation: (classic lock obtain)
|
325
356
|
# NOTE: classic is: acq_process[:result][:process] == :lock_obtaining
|
@@ -343,7 +374,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
343
374
|
acq_time: acq_time,
|
344
375
|
instrument:
|
345
376
|
})
|
346
|
-
end
|
377
|
+
end if instr_sampled
|
347
378
|
end
|
348
379
|
|
349
380
|
# Step 2.1.a: successfully acquired => build the result
|
@@ -452,6 +483,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
452
483
|
ttl,
|
453
484
|
queue_ttl,
|
454
485
|
log_sampled,
|
486
|
+
instr_sampled,
|
455
487
|
should_expire, # NOTE: should expire the lock after the block execution
|
456
488
|
should_decrease, # NOTE: should decrease the lock ttl in reentrant locks?
|
457
489
|
&block
|
@@ -477,7 +509,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
477
509
|
acq_time: acq_process[:acq_time],
|
478
510
|
instrument:
|
479
511
|
})
|
480
|
-
end
|
512
|
+
end if instr_sampled
|
481
513
|
else
|
482
514
|
# Step X (instrumentation): lock_hold_and_release
|
483
515
|
run_non_critical do
|
@@ -490,7 +522,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
490
522
|
acq_time: acq_process[:acq_time],
|
491
523
|
instrument:
|
492
524
|
})
|
493
|
-
end
|
525
|
+
end if instr_sampled
|
494
526
|
end
|
495
527
|
end
|
496
528
|
else
|
@@ -13,10 +13,14 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests
|
|
13
13
|
# @param log_sampling_enabled [Boolean]
|
14
14
|
# @param log_sampling_percent [Integer]
|
15
15
|
# @param log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
16
|
+
# @param instr_sampling_enabled [Boolean]
|
17
|
+
# @param instr_sampling_percent [Integer]
|
18
|
+
# @param instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
16
19
|
# @return [Hash<Symbol,Boolean|Hash<Symbol,Set<String>>>]
|
17
20
|
#
|
18
21
|
# @api private
|
19
22
|
# @since 1.0.0
|
23
|
+
# @version 1.6.0
|
20
24
|
def clear_dead_requests(
|
21
25
|
redis_client,
|
22
26
|
scan_size,
|
@@ -26,7 +30,10 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests
|
|
26
30
|
instrument,
|
27
31
|
log_sampling_enabled,
|
28
32
|
log_sampling_percent,
|
29
|
-
log_sampler
|
33
|
+
log_sampler,
|
34
|
+
instr_sampling_enabled,
|
35
|
+
instr_sampling_percent,
|
36
|
+
instr_sampler
|
30
37
|
)
|
31
38
|
dead_score = RedisQueuedLocks::Resource.acquier_dead_score(dead_ttl / 1_000.0)
|
32
39
|
|
@@ -17,22 +17,32 @@ module RedisQueuedLocks::Acquier::ExtendLockTTL
|
|
17
17
|
# @param lock_name [String]
|
18
18
|
# @param milliseconds [Integer]
|
19
19
|
# @param logger [::Logger,#debug]
|
20
|
+
# @param instrumenter [#notify]
|
21
|
+
# @param instrument [NilClass,Any]
|
20
22
|
# @param log_sampling_enabled [Boolean]
|
21
23
|
# @param log_sampling_percent [Integer]
|
22
24
|
# @param log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
25
|
+
# @param instr_sampling_enabled [Boolean]
|
26
|
+
# @param instr_sampling_percent [Integer]
|
27
|
+
# @param instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
23
28
|
# @return [Hash<Symbol,Boolean|Symbol>]
|
24
29
|
#
|
25
30
|
# @api private
|
26
31
|
# @since 1.0.0
|
27
|
-
# @version 1.
|
32
|
+
# @version 1.6.0
|
28
33
|
def extend_lock_ttl(
|
29
34
|
redis_client,
|
30
35
|
lock_name,
|
31
36
|
milliseconds,
|
32
37
|
logger,
|
38
|
+
instrumenter,
|
39
|
+
instrument,
|
33
40
|
log_sampling_enabled,
|
34
41
|
log_sampling_percent,
|
35
|
-
log_sampler
|
42
|
+
log_sampler,
|
43
|
+
instr_sampling_enabled,
|
44
|
+
instr_sampling_percent,
|
45
|
+
instr_sampler
|
36
46
|
)
|
37
47
|
lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
|
38
48
|
|
@@ -24,19 +24,46 @@ module RedisQueuedLocks::Acquier::ReleaseAllLocks
|
|
24
24
|
# - Custom instrumentation data wich will be passed to the instrumenter's payload
|
25
25
|
# with :instrument key;
|
26
26
|
# @param log_sampling_enabled [Boolean]
|
27
|
-
# -
|
28
|
-
# -
|
27
|
+
# - enables <log sampling>: only the configured percent of RQL cases will be logged;
|
28
|
+
# - disabled by default;
|
29
|
+
# - works in tandem with <config.log_sampling_percent and <log.sampler>;
|
29
30
|
# @param log_sampling_percent [Integer]
|
30
|
-
# -
|
31
|
-
# -
|
32
|
-
#
|
31
|
+
# - the percent of cases that should be logged;
|
32
|
+
# - take an effect when <config.log_sampling_enalbed> is true;
|
33
|
+
# - works in tandem with <config.log_sampling_enabled> and <config.log_sampler> configs;
|
33
34
|
# @param log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
35
|
+
# - percent-based log sampler that decides should be RQL case logged or not;
|
36
|
+
# - works in tandem with <config.log_sampling_enabled> and
|
37
|
+
# <config.log_sampling_percent> configs;
|
38
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
39
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
40
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
41
|
+
# `sampling_happened?(percent) => boolean` interface
|
42
|
+
# (see `RedisQueuedLocks::Logging::Sampler` for example);
|
43
|
+
# @param instr_sampling_enabled [Boolean]
|
44
|
+
# - enables <instrumentaion sampling>: only the configured percent
|
45
|
+
# of RQL cases will be instrumented;
|
46
|
+
# - disabled by default;
|
47
|
+
# - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
|
48
|
+
# @param instr_sampling_percent [Integer]
|
49
|
+
# - the percent of cases that should be instrumented;
|
50
|
+
# - take an effect when <config.instr_sampling_enalbed> is true;
|
51
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
|
52
|
+
# @param instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
53
|
+
# - percent-based log sampler that decides should be RQL case instrumented or not;
|
54
|
+
# - works in tandem with <config.instr_sampling_enabled> and
|
55
|
+
# <config.instr_sampling_percent> configs;
|
56
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
57
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
58
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
59
|
+
# `sampling_happened?(percent) => boolean` interface
|
60
|
+
# (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
34
61
|
# @return [RedisQueuedLocks::Data,Hash<Symbol,Any>]
|
35
62
|
# Format: { ok: true, result: Hash<Symbol,Numeric> }
|
36
63
|
#
|
37
64
|
# @api private
|
38
65
|
# @since 1.0.0
|
39
|
-
# @version 1.
|
66
|
+
# @version 1.6.0
|
40
67
|
def release_all_locks(
|
41
68
|
redis,
|
42
69
|
batch_size,
|
@@ -45,7 +72,10 @@ module RedisQueuedLocks::Acquier::ReleaseAllLocks
|
|
45
72
|
instrument,
|
46
73
|
log_sampling_enabled,
|
47
74
|
log_sampling_percent,
|
48
|
-
log_sampler
|
75
|
+
log_sampler,
|
76
|
+
instr_sampling_enabled,
|
77
|
+
instr_sampling_percent,
|
78
|
+
instr_sampler
|
49
79
|
)
|
50
80
|
rel_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :microsecond)
|
51
81
|
fully_release_all_locks(redis, batch_size) => { ok:, result: }
|
@@ -53,13 +83,19 @@ module RedisQueuedLocks::Acquier::ReleaseAllLocks
|
|
53
83
|
rel_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :microsecond)
|
54
84
|
rel_time = ((rel_end_time - rel_start_time) / 1_000).ceil(2)
|
55
85
|
|
86
|
+
instr_sampled = RedisQueuedLocks::Instrument.should_instrument?(
|
87
|
+
instr_sampling_enabled,
|
88
|
+
instr_sampling_percent,
|
89
|
+
instr_sampler
|
90
|
+
)
|
91
|
+
|
56
92
|
run_non_critical do
|
57
93
|
instrumenter.notify('redis_queued_locks.explicit_all_locks_release', {
|
58
94
|
at: time_at,
|
59
95
|
rel_time: rel_time,
|
60
96
|
rel_key_cnt: result[:rel_key_cnt]
|
61
97
|
})
|
62
|
-
end
|
98
|
+
end if instr_sampled
|
63
99
|
|
64
100
|
RedisQueuedLocks::Data[
|
65
101
|
ok: true,
|
@@ -24,25 +24,47 @@ module RedisQueuedLocks::Acquier::ReleaseLock
|
|
24
24
|
# - Logger object used from `configuration` layer (see config[:logger]);
|
25
25
|
# - See RedisQueuedLocks::Logging::VoidLogger for example;
|
26
26
|
# @param log_sampling_enabled [Boolean]
|
27
|
-
# -
|
28
|
-
# -
|
29
|
-
#
|
30
|
-
# - You can provide your own sampler via config[:log_sampler] config and :sampler option
|
31
|
-
# (see `RedisQueuedLocks::Logging::Sampler` for examples);
|
32
|
-
# - The spread of guaranteed percent is approximately +13% (rand method spread);
|
33
|
-
# - Take an effect when <log_sampling_enabled> parameter has <true> value
|
34
|
-
# (when log sampling is enabled);
|
27
|
+
# - enables <log sampling>: only the configured percent of RQL cases will be logged;
|
28
|
+
# - disabled by default;
|
29
|
+
# - works in tandem with <config.log_sampling_percent and <log.sampler>;
|
35
30
|
# @param log_sampling_percent [Integer]
|
36
|
-
# -
|
37
|
-
# -
|
38
|
-
#
|
31
|
+
# - the percent of cases that should be logged;
|
32
|
+
# - take an effect when <config.log_sampling_enalbed> is true;
|
33
|
+
# - works in tandem with <config.log_sampling_enabled> and <config.log_sampler> configs;
|
39
34
|
# @param log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
35
|
+
# - percent-based log sampler that decides should be RQL case logged or not;
|
36
|
+
# - works in tandem with <config.log_sampling_enabled> and
|
37
|
+
# <config.log_sampling_percent> configs;
|
38
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
39
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
40
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
41
|
+
# `sampling_happened?(percent) => boolean` interface
|
42
|
+
# (see `RedisQueuedLocks::Logging::Sampler` for example);
|
43
|
+
# @param instr_sampling_enabled [Boolean]
|
44
|
+
# - enables <instrumentaion sampling>: only the configured percent
|
45
|
+
# of RQL cases will be instrumented;
|
46
|
+
# - disabled by default;
|
47
|
+
# - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
|
48
|
+
# @param instr_sampling_percent [Integer]
|
49
|
+
# - the percent of cases that should be instrumented;
|
50
|
+
# - take an effect when <config.instr_sampling_enalbed> is true;
|
51
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
|
52
|
+
# @param instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
53
|
+
# - percent-based log sampler that decides should be RQL case instrumented or not;
|
54
|
+
# - works in tandem with <config.instr_sampling_enabled> and
|
55
|
+
# <config.instr_sampling_percent> configs;
|
56
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses
|
57
|
+
# SecureRandom.rand method so the algorithm error is ~(0%..13%);
|
58
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
59
|
+
# `sampling_happened?(percent) => boolean` interface
|
60
|
+
# (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
40
61
|
# @return [RedisQueuedLocks::Data,Hash<Symbol,Boolean<Hash<Symbol,Numeric|String|Symbol>>]
|
41
62
|
# Format: { ok: true/false, result: Hash<Symbol,Numeric|String|Symbol> }
|
42
63
|
#
|
43
64
|
# @api private
|
44
65
|
# @since 1.0.0
|
45
|
-
# @version 1.
|
66
|
+
# @version 1.6.0
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
46
68
|
def release_lock(
|
47
69
|
redis,
|
48
70
|
lock_name,
|
@@ -50,7 +72,10 @@ module RedisQueuedLocks::Acquier::ReleaseLock
|
|
50
72
|
logger,
|
51
73
|
log_sampling_enabled,
|
52
74
|
log_sampling_percent,
|
53
|
-
log_sampler
|
75
|
+
log_sampler,
|
76
|
+
instr_sampling_enabled,
|
77
|
+
instr_sampling_percent,
|
78
|
+
instr_sampler
|
54
79
|
)
|
55
80
|
lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
|
56
81
|
lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
|
@@ -61,6 +86,12 @@ module RedisQueuedLocks::Acquier::ReleaseLock
|
|
61
86
|
rel_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :microsecond)
|
62
87
|
rel_time = ((rel_end_time - rel_start_time) / 1_000).ceil(2)
|
63
88
|
|
89
|
+
instr_sampled = RedisQueuedLocks::Instrument.should_instrument?(
|
90
|
+
instr_sampling_enabled,
|
91
|
+
instr_sampling_percent,
|
92
|
+
instr_sampler
|
93
|
+
)
|
94
|
+
|
64
95
|
run_non_critical do
|
65
96
|
instrumenter.notify('redis_queued_locks.explicit_lock_release', {
|
66
97
|
lock_key: lock_key,
|
@@ -68,7 +99,7 @@ module RedisQueuedLocks::Acquier::ReleaseLock
|
|
68
99
|
rel_time: rel_time,
|
69
100
|
at: time_at
|
70
101
|
})
|
71
|
-
end
|
102
|
+
end if instr_sampled
|
72
103
|
|
73
104
|
RedisQueuedLocks::Data[
|
74
105
|
ok: true,
|
@@ -81,6 +112,7 @@ module RedisQueuedLocks::Acquier::ReleaseLock
|
|
81
112
|
}
|
82
113
|
]
|
83
114
|
end
|
115
|
+
# rubocop:enable Metrics/MethodLength
|
84
116
|
|
85
117
|
private
|
86
118
|
|
@@ -26,6 +26,9 @@ class RedisQueuedLocks::Client
|
|
26
26
|
setting :log_sampling_enabled, false
|
27
27
|
setting :log_sampling_percent, 15
|
28
28
|
setting :log_sampler, RedisQueuedLocks::Logging::Sampler
|
29
|
+
setting :instr_sampling_enabled, false
|
30
|
+
setting :instr_sampling_percent, 15
|
31
|
+
setting :instr_sampler, RedisQueuedLocks::Instrument::Sampler
|
29
32
|
|
30
33
|
validate('retry_count') { |val| val == nil || (val.is_a?(::Integer) && val >= 0) }
|
31
34
|
validate('retry_delay') { |val| val.is_a?(::Integer) && val >= 0 }
|
@@ -43,6 +46,9 @@ class RedisQueuedLocks::Client
|
|
43
46
|
validate('log_sampler') { |val| RedisQueuedLocks::Logging.valid_sampler?(val) }
|
44
47
|
validate('log_sampling_enabled', :boolean)
|
45
48
|
validate('log_sampling_percent') { |val| val.is_a?(::Integer) && val >= 0 && val <= 100 }
|
49
|
+
validate('instr_sampling_enabled', :boolean)
|
50
|
+
validate('instr_sampling_percent') { |val| val.is_a?(::Integer) && val >= 0 && val <= 100 }
|
51
|
+
validate('instr_sampler') { |val| RedisQueuedLocks::Instrument.valid_sampler?(val) }
|
46
52
|
validate('default_conflict_strategy') do |val|
|
47
53
|
# rubocop:disable Layout/MultilineOperationIndentation
|
48
54
|
val == :work_through ||
|
@@ -98,8 +104,6 @@ class RedisQueuedLocks::Client
|
|
98
104
|
# A time-interval between the each retry (in milliseconds).
|
99
105
|
# @option retry_jitter [Integer]
|
100
106
|
# Time-shift range for retry-delay (in milliseconds).
|
101
|
-
# @option instrumenter [#notify]
|
102
|
-
# See RedisQueuedLocks::Instrument::ActiveSupport for example.
|
103
107
|
# @option raise_errors [Boolean]
|
104
108
|
# Raise errors on library-related limits such as timeout or failed lock obtain.
|
105
109
|
# @option identity [String]
|
@@ -133,6 +137,12 @@ class RedisQueuedLocks::Client
|
|
133
137
|
# - should be logged the each try of lock acquiring (a lot of logs can
|
134
138
|
# be generated depending on your retry configurations);
|
135
139
|
# - see `config[:log_lock_try]`;
|
140
|
+
# @option instrumenter [#notify]
|
141
|
+
# - Custom instrumenter that will be invoked via #notify method with `event` and `payload` data;
|
142
|
+
# - See RedisQueuedLocks::Instrument::ActiveSupport for examples and implementation details;
|
143
|
+
# - See [Instrumentation](#instrumentation) section of docs;
|
144
|
+
# - pre-configured in `config[:isntrumenter]` with void notifier
|
145
|
+
# (`RedisQueuedLocks::Instrumenter::VoidNotifier`);
|
136
146
|
# @option instrument [NilClass,Any]
|
137
147
|
# - Custom instrumentation data wich will be passed to the instrumenter's payload
|
138
148
|
# with :instrument key;
|
@@ -153,6 +163,24 @@ class RedisQueuedLocks::Client
|
|
153
163
|
# - you can provide your own log sampler with bettter algorithm that should realize
|
154
164
|
# `sampling_happened?(percent) => boolean` interface
|
155
165
|
# (see `RedisQueuedLocks::Logging::Sampler` for example);
|
166
|
+
# @option instr_sampling_enabled [Boolean]
|
167
|
+
# - enables <instrumentaion sampling>: only the configured percent
|
168
|
+
# of RQL cases will be instrumented;
|
169
|
+
# - disabled by default;
|
170
|
+
# - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
|
171
|
+
# @option instr_sampling_percent [Integer]
|
172
|
+
# - the percent of cases that should be instrumented;
|
173
|
+
# - take an effect when <config.instr_sampling_enalbed> is true;
|
174
|
+
# - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
|
175
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
176
|
+
# - percent-based log sampler that decides should be RQL case instrumented or not;
|
177
|
+
# - works in tandem with <config.instr_sampling_enabled> and
|
178
|
+
# <config.instr_sampling_percent> configs;
|
179
|
+
# - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
|
180
|
+
# method so the algorithm error is ~(0%..13%);
|
181
|
+
# - you can provide your own log sampler with bettter algorithm that should realize
|
182
|
+
# `sampling_happened?(percent) => boolean` interface
|
183
|
+
# (see `RedisQueuedLocks::Instrument::Sampler` for example);
|
156
184
|
# @param block [Block]
|
157
185
|
# A block of code that should be executed after the successfully acquired lock.
|
158
186
|
# @return [RedisQueuedLocks::Data,Hash<Symbol,Any>,yield]
|
@@ -161,7 +189,7 @@ class RedisQueuedLocks::Client
|
|
161
189
|
#
|
162
190
|
# @api public
|
163
191
|
# @since 1.0.0
|
164
|
-
# @version 1.
|
192
|
+
# @version 1.6.0
|
165
193
|
# rubocop:disable Metrics/MethodLength
|
166
194
|
def lock(
|
167
195
|
lock_name,
|
@@ -179,10 +207,14 @@ class RedisQueuedLocks::Client
|
|
179
207
|
meta: nil,
|
180
208
|
logger: config[:logger],
|
181
209
|
log_lock_try: config[:log_lock_try],
|
210
|
+
instrumenter: config[:instrumenter],
|
182
211
|
instrument: nil,
|
183
212
|
log_sampling_enabled: config[:log_sampling_enabled],
|
184
213
|
log_sampling_percent: config[:log_sampling_percent],
|
185
214
|
log_sampler: config[:log_sampler],
|
215
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
216
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
217
|
+
instr_sampler: config[:instr_sampler],
|
186
218
|
&block
|
187
219
|
)
|
188
220
|
RedisQueuedLocks::Acquier::AcquireLock.acquire_lock(
|
@@ -200,7 +232,7 @@ class RedisQueuedLocks::Client
|
|
200
232
|
retry_delay:,
|
201
233
|
retry_jitter:,
|
202
234
|
raise_errors:,
|
203
|
-
instrumenter
|
235
|
+
instrumenter:,
|
204
236
|
identity:,
|
205
237
|
fail_fast:,
|
206
238
|
conflict_strategy:,
|
@@ -211,6 +243,9 @@ class RedisQueuedLocks::Client
|
|
211
243
|
log_sampling_enabled:,
|
212
244
|
log_sampling_percent:,
|
213
245
|
log_sampler:,
|
246
|
+
instr_sampling_enabled:,
|
247
|
+
instr_sampling_percent:,
|
248
|
+
instr_sampler:,
|
214
249
|
&block
|
215
250
|
)
|
216
251
|
end
|
@@ -220,7 +255,8 @@ class RedisQueuedLocks::Client
|
|
220
255
|
#
|
221
256
|
# @api public
|
222
257
|
# @since 1.0.0
|
223
|
-
# @version 1.
|
258
|
+
# @version 1.6.0
|
259
|
+
# rubocop:disable Metrics/MethodLength
|
224
260
|
def lock!(
|
225
261
|
lock_name,
|
226
262
|
ttl: config[:default_lock_ttl],
|
@@ -233,6 +269,7 @@ class RedisQueuedLocks::Client
|
|
233
269
|
fail_fast: false,
|
234
270
|
conflict_strategy: config[:default_conflict_strategy],
|
235
271
|
identity: uniq_identity,
|
272
|
+
instrumenter: config[:instrumenter],
|
236
273
|
meta: nil,
|
237
274
|
logger: config[:logger],
|
238
275
|
log_lock_try: config[:log_lock_try],
|
@@ -240,6 +277,9 @@ class RedisQueuedLocks::Client
|
|
240
277
|
log_sampling_enabled: config[:log_sampling_enabled],
|
241
278
|
log_sampling_percent: config[:log_sampling_percent],
|
242
279
|
log_sampler: config[:log_sampler],
|
280
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
281
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
282
|
+
instr_sampler: config[:instr_sampler],
|
243
283
|
&block
|
244
284
|
)
|
245
285
|
lock(
|
@@ -258,13 +298,18 @@ class RedisQueuedLocks::Client
|
|
258
298
|
log_lock_try:,
|
259
299
|
meta:,
|
260
300
|
instrument:,
|
301
|
+
instrumenter:,
|
261
302
|
conflict_strategy:,
|
262
303
|
log_sampling_enabled:,
|
263
304
|
log_sampling_percent:,
|
264
305
|
log_sampler:,
|
306
|
+
instr_sampling_enabled:,
|
307
|
+
instr_sampling_percent:,
|
308
|
+
instr_sampler:,
|
265
309
|
&block
|
266
310
|
)
|
267
311
|
end
|
312
|
+
# rubocop:enable Metrics/MethodLength
|
268
313
|
|
269
314
|
# @param lock_name [String] The lock name that should be released.
|
270
315
|
# @option logger [::Logger,#debug]
|
@@ -273,6 +318,9 @@ class RedisQueuedLocks::Client
|
|
273
318
|
# @option log_sampling_enabled [Boolean]
|
274
319
|
# @option log_sampling_percent [Integer]
|
275
320
|
# @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
321
|
+
# @option instr_sampling_enabled [Boolean]
|
322
|
+
# @option instr_sampling_percent [Integer]
|
323
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
276
324
|
# @return [RedisQueuedLocks::Data, Hash<Symbol,Any>]
|
277
325
|
# Format: {
|
278
326
|
# ok: true/false,
|
@@ -287,7 +335,7 @@ class RedisQueuedLocks::Client
|
|
287
335
|
#
|
288
336
|
# @api public
|
289
337
|
# @since 1.0.0
|
290
|
-
# @version 1.
|
338
|
+
# @version 1.6.0
|
291
339
|
def unlock(
|
292
340
|
lock_name,
|
293
341
|
logger: config[:logger],
|
@@ -295,16 +343,22 @@ class RedisQueuedLocks::Client
|
|
295
343
|
instrument: nil,
|
296
344
|
log_sampling_enabled: config[:log_sampling_enabled],
|
297
345
|
log_sampling_percent: config[:log_sampling_percent],
|
298
|
-
log_sampler: config[:log_sampler]
|
346
|
+
log_sampler: config[:log_sampler],
|
347
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
348
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
349
|
+
instr_sampler: config[:instr_sampler]
|
299
350
|
)
|
300
351
|
RedisQueuedLocks::Acquier::ReleaseLock.release_lock(
|
301
352
|
redis_client,
|
302
353
|
lock_name,
|
303
|
-
|
304
|
-
|
354
|
+
instrumenter,
|
355
|
+
logger,
|
305
356
|
log_sampling_enabled,
|
306
357
|
log_sampling_percent,
|
307
|
-
log_sampler
|
358
|
+
log_sampler,
|
359
|
+
instr_sampling_enabled,
|
360
|
+
instr_sampling_percent,
|
361
|
+
instr_sampler
|
308
362
|
)
|
309
363
|
end
|
310
364
|
|
@@ -358,43 +412,47 @@ class RedisQueuedLocks::Client
|
|
358
412
|
# @param lock_name [String]
|
359
413
|
# @param milliseconds [Integer] How many milliseconds should be added.
|
360
414
|
# @option logger [::Logger,#debug]
|
415
|
+
# @option instrumenter [#notify] See `config[:instrumenter]` docs for details.
|
416
|
+
# @option instrument [NilClass,Any]
|
361
417
|
# @option log_sampling_enabled [Boolean]
|
362
|
-
# - The percent of cases that should be logged;
|
363
|
-
# - Sampling algorithm is super simple and works via SecureRandom.rand method
|
364
|
-
# on the base of "weight" algorithm;
|
365
|
-
# - You can provide your own sampler via config[:log_sampler] config and :sampler option
|
366
|
-
# (see `RedisQueuedLocks::Logging::Sampler` for examples);
|
367
|
-
# - The spread of guaranteed percent is approximately +13% (rand method spread);
|
368
|
-
# - Take an effect when <log_sampling_enabled> parameter has <true> value
|
369
|
-
# (when log sampling is enabled);
|
370
418
|
# @option log_sampling_percent [Integer]
|
371
|
-
# - The percent of cases that should be logged;
|
372
|
-
# - Take an effect when <log_sampling_enabled> parameter has <true> value
|
373
|
-
# (when log sampling is enabled);
|
374
419
|
# @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
420
|
+
# @option instr_sampling_enabled [Boolean]
|
421
|
+
# @option instr_sampling_percent [Integer]
|
422
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
375
423
|
# @return [Hash<Symbol,Boolean|Symbol>]
|
376
424
|
# - { ok: true, result: :ttl_extended }
|
377
425
|
# - { ok: false, result: :async_expire_or_no_lock }
|
378
426
|
#
|
379
427
|
# @api public
|
380
428
|
# @since 1.0.0
|
381
|
-
# @version 1.
|
429
|
+
# @version 1.6.0
|
382
430
|
def extend_lock_ttl(
|
383
431
|
lock_name,
|
384
432
|
milliseconds,
|
385
433
|
logger: config[:logger],
|
434
|
+
instrumenter: config[:instrumenter],
|
435
|
+
instrument: nil,
|
386
436
|
log_sampling_enabled: config[:log_sampling_enabled],
|
387
437
|
log_sampling_percent: config[:log_sampling_percent],
|
388
|
-
log_sampler: config[:log_sampler]
|
438
|
+
log_sampler: config[:log_sampler],
|
439
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
440
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
441
|
+
instr_sampler: config[:instr_sampler]
|
389
442
|
)
|
390
443
|
RedisQueuedLocks::Acquier::ExtendLockTTL.extend_lock_ttl(
|
391
444
|
redis_client,
|
392
445
|
lock_name,
|
393
446
|
milliseconds,
|
394
447
|
logger,
|
448
|
+
instrumenter,
|
449
|
+
instrument,
|
395
450
|
log_sampling_enabled,
|
396
451
|
log_sampling_percent,
|
397
|
-
log_sampler
|
452
|
+
log_sampler,
|
453
|
+
instr_sampling_enabled,
|
454
|
+
instr_sampling_percent,
|
455
|
+
instr_sampler
|
398
456
|
)
|
399
457
|
end
|
400
458
|
|
@@ -405,17 +463,20 @@ class RedisQueuedLocks::Client
|
|
405
463
|
#
|
406
464
|
# @option batch_size [Integer]
|
407
465
|
# @option logger [::Logger,#debug]
|
408
|
-
# @option instrumenter [#notify]
|
466
|
+
# @option instrumenter [#notify] See `config[:instrumenter]` docs for details.
|
409
467
|
# @option instrument [NilClass,Any]
|
410
468
|
# @option log_sampling_enabled [Boolean]
|
411
469
|
# @option log_sampling_percent [Integer]
|
412
470
|
# @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
471
|
+
# @option instr_sampling_enabled [Boolean]
|
472
|
+
# @option instr_sampling_percent [Integer]
|
473
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
413
474
|
# @return [RedisQueuedLocks::Data,Hash<Symbol,Boolean|Hash<Symbol,Numeric>>]
|
414
475
|
# Example: { ok: true, result { rel_key_cnt: 100, rel_time: 0.01 } }
|
415
476
|
#
|
416
477
|
# @api public
|
417
478
|
# @since 1.0.0
|
418
|
-
# @version 1.
|
479
|
+
# @version 1.6.0
|
419
480
|
def clear_locks(
|
420
481
|
batch_size: config[:lock_release_batch_size],
|
421
482
|
logger: config[:logger],
|
@@ -423,7 +484,10 @@ class RedisQueuedLocks::Client
|
|
423
484
|
instrument: nil,
|
424
485
|
log_sampling_enabled: config[:log_sampling_enabled],
|
425
486
|
log_sampling_percent: config[:log_sampling_percent],
|
426
|
-
log_sampler: config[:log_sampler]
|
487
|
+
log_sampler: config[:log_sampler],
|
488
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
489
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
490
|
+
instr_sampler: config[:instr_sampler]
|
427
491
|
)
|
428
492
|
RedisQueuedLocks::Acquier::ReleaseAllLocks.release_all_locks(
|
429
493
|
redis_client,
|
@@ -433,7 +497,10 @@ class RedisQueuedLocks::Client
|
|
433
497
|
instrument,
|
434
498
|
log_sampling_enabled,
|
435
499
|
log_sampling_percent,
|
436
|
-
log_sampler
|
500
|
+
log_sampler,
|
501
|
+
instr_sampling_enabled,
|
502
|
+
instr_sampling_percent,
|
503
|
+
instr_sampler
|
437
504
|
)
|
438
505
|
end
|
439
506
|
|
@@ -524,12 +591,15 @@ class RedisQueuedLocks::Client
|
|
524
591
|
# @option log_sampling_enabled [Boolean]
|
525
592
|
# @option log_sampling_percent [Integer]
|
526
593
|
# @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
|
594
|
+
# @option instr_sampling_enabled [Boolean]
|
595
|
+
# @option instr_sampling_percent [Integer]
|
596
|
+
# @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
527
597
|
# @return [Hash<Symbol,Boolean|Hash<Symbol,Set<String>>>]
|
528
598
|
# Format: { ok: true, result: { processed_queus: Set<String> } }
|
529
599
|
#
|
530
600
|
# @api public
|
531
601
|
# @since 1.0.0
|
532
|
-
# @version 1.
|
602
|
+
# @version 1.6.0
|
533
603
|
def clear_dead_requests(
|
534
604
|
dead_ttl: config[:dead_request_ttl],
|
535
605
|
scan_size: config[:lock_release_batch_size],
|
@@ -538,7 +608,10 @@ class RedisQueuedLocks::Client
|
|
538
608
|
instrument: nil,
|
539
609
|
log_sampling_enabled: config[:log_sampling_enabled],
|
540
610
|
log_sampling_percent: config[:log_sampling_percent],
|
541
|
-
log_sampler: config[:log_sampler]
|
611
|
+
log_sampler: config[:log_sampler],
|
612
|
+
instr_sampling_enabled: config[:instr_sampling_enabled],
|
613
|
+
instr_sampling_percent: config[:instr_sampling_percent],
|
614
|
+
instr_sampler: config[:instr_sampler]
|
542
615
|
)
|
543
616
|
RedisQueuedLocks::Acquier::ClearDeadRequests.clear_dead_requests(
|
544
617
|
redis_client,
|
@@ -549,7 +622,10 @@ class RedisQueuedLocks::Client
|
|
549
622
|
instrument,
|
550
623
|
log_sampling_enabled,
|
551
624
|
log_sampling_percent,
|
552
|
-
log_sampler
|
625
|
+
log_sampler,
|
626
|
+
instr_sampling_enabled,
|
627
|
+
instr_sampling_percent,
|
628
|
+
instr_sampler
|
553
629
|
)
|
554
630
|
end
|
555
631
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api public
|
4
|
+
# @since 1.6.0
|
5
|
+
module RedisQueuedLocks::Instrument::Sampler
|
6
|
+
# @return [Range]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 1.6.0
|
10
|
+
SAMPLING_PERCENT_RANGE = (0..100)
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Super simple probalistic function based on the `weight` of <true>/<false> values.
|
14
|
+
# Requires the <percent> parameter as the required percent of <true> values sampled.
|
15
|
+
#
|
16
|
+
# @param sampling_percent [Integer]
|
17
|
+
# - percent of <true> values in range of 0..100;
|
18
|
+
# @return [Boolean]
|
19
|
+
# - <true> for <sampling_percent>% of invocations (and <false> for the rest invocations)
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
# @since 1.6.0
|
23
|
+
def sampling_happened?(sampling_percent)
|
24
|
+
sampling_percent >= SecureRandom.rand(SAMPLING_PERCENT_RANGE)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -2,11 +2,58 @@
|
|
2
2
|
|
3
3
|
# @api public
|
4
4
|
# @since 1.0.0
|
5
|
+
# @version 1.6.0
|
5
6
|
module RedisQueuedLocks::Instrument
|
6
7
|
require_relative 'instrument/void_notifier'
|
7
8
|
require_relative 'instrument/active_support'
|
9
|
+
require_relative 'instrument/sampler'
|
8
10
|
|
9
11
|
class << self
|
12
|
+
# @param instr_sampling_enabled [Boolean]
|
13
|
+
# @param instr_sampling_percent [Integer]
|
14
|
+
# @param instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
15
|
+
# @return [Boolean]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 1.6.0
|
19
|
+
def should_instrument?(instr_sampling_enabled, instr_sampling_percent, instr_sampler)
|
20
|
+
return true unless instr_sampling_enabled
|
21
|
+
instr_sampler.sampling_happened?(instr_sampling_percent)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
|
25
|
+
# @return [Boolean]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 1.6.0
|
29
|
+
def valid_sampler?(sampler)
|
30
|
+
return false unless sampler.respond_to?(:sampling_happened?)
|
31
|
+
|
32
|
+
m_obj = sampler.method(:sampling_happened?)
|
33
|
+
m_sig = m_obj.parameters
|
34
|
+
|
35
|
+
# NOTE:
|
36
|
+
# Required method signature (sampling_percent)
|
37
|
+
# => [[:req, :sampling_percent]]
|
38
|
+
# => [[:opt, :sampling_percent]]
|
39
|
+
# => [[:req, :sampling_percent], [:block, :block]]
|
40
|
+
# => [[:opt, :sampling_percent], [:block, :block]]
|
41
|
+
if m_sig.size == 1
|
42
|
+
prm = m_sig[0][0]
|
43
|
+
prm == :req || prm == :opt
|
44
|
+
elsif m_sig.size == 2
|
45
|
+
f_prm = m_sig[0][0]
|
46
|
+
s_prm = m_sign[1][0]
|
47
|
+
|
48
|
+
# rubocop:disable Layout/MultilineOperationIndentation
|
49
|
+
f_prm == :req && s_prm == :block ||
|
50
|
+
f_prm == :opt && s_prm == :block
|
51
|
+
# rubocop:enable Layout/MultilineOperationIndentation
|
52
|
+
else
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
10
57
|
# @param instrumenter [Class,Module,Object]
|
11
58
|
# @return [Boolean]
|
12
59
|
#
|
@@ -1,8 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# @api
|
3
|
+
# @api public
|
4
4
|
# @since 1.5.0
|
5
5
|
module RedisQueuedLocks::Logging::Sampler
|
6
|
+
# @return [Range]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 1.6.0
|
10
|
+
SAMPLING_PERCENT_RANGE = (0..100)
|
11
|
+
|
6
12
|
class << self
|
7
13
|
# Super simple probalistic function based on the `weight` of <true>/<false> values.
|
8
14
|
# Requires the <percent> parameter as the required percent of <true> values sampled.
|
@@ -12,10 +18,11 @@ module RedisQueuedLocks::Logging::Sampler
|
|
12
18
|
# @return [Boolean]
|
13
19
|
# - <true> for <sampling_percent>% of invocations (and <false> for the rest invocations)
|
14
20
|
#
|
15
|
-
# @api
|
21
|
+
# @api public
|
16
22
|
# @since 1.5.0
|
23
|
+
# @version 1.6.0
|
17
24
|
def sampling_happened?(sampling_percent)
|
18
|
-
sampling_percent >= SecureRandom.rand(
|
25
|
+
sampling_percent >= SecureRandom.rand(SAMPLING_PERCENT_RANGE)
|
19
26
|
end
|
20
27
|
end
|
21
28
|
end
|
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.6.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-05-
|
11
|
+
date: 2024-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- lib/redis_queued_locks/errors.rb
|
80
80
|
- lib/redis_queued_locks/instrument.rb
|
81
81
|
- lib/redis_queued_locks/instrument/active_support.rb
|
82
|
+
- lib/redis_queued_locks/instrument/sampler.rb
|
82
83
|
- lib/redis_queued_locks/instrument/void_notifier.rb
|
83
84
|
- lib/redis_queued_locks/logging.rb
|
84
85
|
- lib/redis_queued_locks/logging/sampler.rb
|
@@ -109,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
110
|
- !ruby/object:Gem::Version
|
110
111
|
version: '0'
|
111
112
|
requirements: []
|
112
|
-
rubygems_version: 3.
|
113
|
+
rubygems_version: 3.3.7
|
113
114
|
signing_key:
|
114
115
|
specification_version: 4
|
115
116
|
summary: Queued distributed locks based on Redis.
|