redis_queued_locks 1.5.0 → 1.6.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 +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.
|