redis_queued_locks 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,9 +23,13 @@ class RedisQueuedLocks::Client
23
23
  setting :dead_request_ttl, (1 * 24 * 60 * 60 * 1000) # NOTE: 1 day in milliseconds
24
24
  setting :is_timed_by_default, false
25
25
  setting :default_conflict_strategy, :wait_for_lock
26
+ setting :default_access_strategy, :queued
26
27
  setting :log_sampling_enabled, false
27
28
  setting :log_sampling_percent, 15
28
29
  setting :log_sampler, RedisQueuedLocks::Logging::Sampler
30
+ setting :instr_sampling_enabled, false
31
+ setting :instr_sampling_percent, 15
32
+ setting :instr_sampler, RedisQueuedLocks::Instrument::Sampler
29
33
 
30
34
  validate('retry_count') { |val| val == nil || (val.is_a?(::Integer) && val >= 0) }
31
35
  validate('retry_delay') { |val| val.is_a?(::Integer) && val >= 0 }
@@ -43,6 +47,9 @@ class RedisQueuedLocks::Client
43
47
  validate('log_sampler') { |val| RedisQueuedLocks::Logging.valid_sampler?(val) }
44
48
  validate('log_sampling_enabled', :boolean)
45
49
  validate('log_sampling_percent') { |val| val.is_a?(::Integer) && val >= 0 && val <= 100 }
50
+ validate('instr_sampling_enabled', :boolean)
51
+ validate('instr_sampling_percent') { |val| val.is_a?(::Integer) && val >= 0 && val <= 100 }
52
+ validate('instr_sampler') { |val| RedisQueuedLocks::Instrument.valid_sampler?(val) }
46
53
  validate('default_conflict_strategy') do |val|
47
54
  # rubocop:disable Layout/MultilineOperationIndentation
48
55
  val == :work_through ||
@@ -51,6 +58,12 @@ class RedisQueuedLocks::Client
51
58
  val == :dead_locking
52
59
  # rubocop:enable Layout/MultilineOperationIndentation
53
60
  end
61
+ validate('default_access_strategy') do |val|
62
+ # rubocop:disable Layout/MultilineOperationIndentation
63
+ val == :queued ||
64
+ val == :random
65
+ # rubocop:enable Layout/MultilineOperationIndentation
66
+ end
54
67
  end
55
68
 
56
69
  # @return [RedisClient]
@@ -98,8 +111,6 @@ class RedisQueuedLocks::Client
98
111
  # A time-interval between the each retry (in milliseconds).
99
112
  # @option retry_jitter [Integer]
100
113
  # Time-shift range for retry-delay (in milliseconds).
101
- # @option instrumenter [#notify]
102
- # See RedisQueuedLocks::Instrument::ActiveSupport for example.
103
114
  # @option raise_errors [Boolean]
104
115
  # Raise errors on library-related limits such as timeout or failed lock obtain.
105
116
  # @option identity [String]
@@ -122,6 +133,16 @@ class RedisQueuedLocks::Client
122
133
  # - `:wait_for_lock` - (default) - work in classic way
123
134
  # (with timeouts, retry delays, retry limits, etc - in classic way :));
124
135
  # - `:dead_locking` - fail with deadlock exception;
136
+ # @option access_strategy [Symbol]
137
+ # - The way in which the lock will be obtained;
138
+ # - By default it uses `:queued` strategy;
139
+ # - Supports following strategies:
140
+ # - `:queued` (FIFO): the classic queued behavior (default), your lock will be
141
+ # obitaned if you are first in queue and the required lock is free;
142
+ # - `:random` (RANDOM): obtain a lock without checking the positions in the queue
143
+ # (but with checking the limist, retries, timeouts and so on). if lock is
144
+ # free to obtain - it will be obtained;
145
+ # - pre-configured in `config[:default_access_strategy]`;
125
146
  # @option meta [NilClass,Hash<String|Symbol,Any>]
126
147
  # - A custom metadata wich will be passed to the lock data in addition to the existing data;
127
148
  # - Metadata can not contain reserved lock data keys;
@@ -133,6 +154,12 @@ class RedisQueuedLocks::Client
133
154
  # - should be logged the each try of lock acquiring (a lot of logs can
134
155
  # be generated depending on your retry configurations);
135
156
  # - see `config[:log_lock_try]`;
157
+ # @option instrumenter [#notify]
158
+ # - Custom instrumenter that will be invoked via #notify method with `event` and `payload` data;
159
+ # - See RedisQueuedLocks::Instrument::ActiveSupport for examples and implementation details;
160
+ # - See [Instrumentation](#instrumentation) section of docs;
161
+ # - pre-configured in `config[:isntrumenter]` with void notifier
162
+ # (`RedisQueuedLocks::Instrumenter::VoidNotifier`);
136
163
  # @option instrument [NilClass,Any]
137
164
  # - Custom instrumentation data wich will be passed to the instrumenter's payload
138
165
  # with :instrument key;
@@ -153,6 +180,24 @@ class RedisQueuedLocks::Client
153
180
  # - you can provide your own log sampler with bettter algorithm that should realize
154
181
  # `sampling_happened?(percent) => boolean` interface
155
182
  # (see `RedisQueuedLocks::Logging::Sampler` for example);
183
+ # @option instr_sampling_enabled [Boolean]
184
+ # - enables <instrumentaion sampling>: only the configured percent
185
+ # of RQL cases will be instrumented;
186
+ # - disabled by default;
187
+ # - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
188
+ # @option instr_sampling_percent [Integer]
189
+ # - the percent of cases that should be instrumented;
190
+ # - take an effect when <config.instr_sampling_enalbed> is true;
191
+ # - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
192
+ # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
193
+ # - percent-based log sampler that decides should be RQL case instrumented or not;
194
+ # - works in tandem with <config.instr_sampling_enabled> and
195
+ # <config.instr_sampling_percent> configs;
196
+ # - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
197
+ # method so the algorithm error is ~(0%..13%);
198
+ # - you can provide your own log sampler with bettter algorithm that should realize
199
+ # `sampling_happened?(percent) => boolean` interface
200
+ # (see `RedisQueuedLocks::Instrument::Sampler` for example);
156
201
  # @param block [Block]
157
202
  # A block of code that should be executed after the successfully acquired lock.
158
203
  # @return [RedisQueuedLocks::Data,Hash<Symbol,Any>,yield]
@@ -161,7 +206,7 @@ class RedisQueuedLocks::Client
161
206
  #
162
207
  # @api public
163
208
  # @since 1.0.0
164
- # @version 1.5.0
209
+ # @version 1.7.0
165
210
  # rubocop:disable Metrics/MethodLength
166
211
  def lock(
167
212
  lock_name,
@@ -175,14 +220,19 @@ class RedisQueuedLocks::Client
175
220
  raise_errors: false,
176
221
  fail_fast: false,
177
222
  conflict_strategy: config[:default_conflict_strategy],
223
+ access_strategy: config[:default_access_strategy],
178
224
  identity: uniq_identity,
179
225
  meta: nil,
180
226
  logger: config[:logger],
181
227
  log_lock_try: config[:log_lock_try],
228
+ instrumenter: config[:instrumenter],
182
229
  instrument: nil,
183
230
  log_sampling_enabled: config[:log_sampling_enabled],
184
231
  log_sampling_percent: config[:log_sampling_percent],
185
232
  log_sampler: config[:log_sampler],
233
+ instr_sampling_enabled: config[:instr_sampling_enabled],
234
+ instr_sampling_percent: config[:instr_sampling_percent],
235
+ instr_sampler: config[:instr_sampler],
186
236
  &block
187
237
  )
188
238
  RedisQueuedLocks::Acquier::AcquireLock.acquire_lock(
@@ -200,10 +250,11 @@ class RedisQueuedLocks::Client
200
250
  retry_delay:,
201
251
  retry_jitter:,
202
252
  raise_errors:,
203
- instrumenter: config[:instrumenter],
253
+ instrumenter:,
204
254
  identity:,
205
255
  fail_fast:,
206
256
  conflict_strategy:,
257
+ access_strategy:,
207
258
  meta:,
208
259
  logger:,
209
260
  log_lock_try:,
@@ -211,6 +262,9 @@ class RedisQueuedLocks::Client
211
262
  log_sampling_enabled:,
212
263
  log_sampling_percent:,
213
264
  log_sampler:,
265
+ instr_sampling_enabled:,
266
+ instr_sampling_percent:,
267
+ instr_sampler:,
214
268
  &block
215
269
  )
216
270
  end
@@ -220,7 +274,8 @@ class RedisQueuedLocks::Client
220
274
  #
221
275
  # @api public
222
276
  # @since 1.0.0
223
- # @version 1.5.0
277
+ # @version 1.7.0
278
+ # rubocop:disable Metrics/MethodLength
224
279
  def lock!(
225
280
  lock_name,
226
281
  ttl: config[:default_lock_ttl],
@@ -232,7 +287,9 @@ class RedisQueuedLocks::Client
232
287
  retry_jitter: config[:retry_jitter],
233
288
  fail_fast: false,
234
289
  conflict_strategy: config[:default_conflict_strategy],
290
+ access_strategy: config[:default_access_strategy],
235
291
  identity: uniq_identity,
292
+ instrumenter: config[:instrumenter],
236
293
  meta: nil,
237
294
  logger: config[:logger],
238
295
  log_lock_try: config[:log_lock_try],
@@ -240,6 +297,9 @@ class RedisQueuedLocks::Client
240
297
  log_sampling_enabled: config[:log_sampling_enabled],
241
298
  log_sampling_percent: config[:log_sampling_percent],
242
299
  log_sampler: config[:log_sampler],
300
+ instr_sampling_enabled: config[:instr_sampling_enabled],
301
+ instr_sampling_percent: config[:instr_sampling_percent],
302
+ instr_sampler: config[:instr_sampler],
243
303
  &block
244
304
  )
245
305
  lock(
@@ -258,13 +318,19 @@ class RedisQueuedLocks::Client
258
318
  log_lock_try:,
259
319
  meta:,
260
320
  instrument:,
321
+ instrumenter:,
261
322
  conflict_strategy:,
323
+ access_strategy:,
262
324
  log_sampling_enabled:,
263
325
  log_sampling_percent:,
264
326
  log_sampler:,
327
+ instr_sampling_enabled:,
328
+ instr_sampling_percent:,
329
+ instr_sampler:,
265
330
  &block
266
331
  )
267
332
  end
333
+ # rubocop:enable Metrics/MethodLength
268
334
 
269
335
  # @param lock_name [String] The lock name that should be released.
270
336
  # @option logger [::Logger,#debug]
@@ -273,6 +339,9 @@ class RedisQueuedLocks::Client
273
339
  # @option log_sampling_enabled [Boolean]
274
340
  # @option log_sampling_percent [Integer]
275
341
  # @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
342
+ # @option instr_sampling_enabled [Boolean]
343
+ # @option instr_sampling_percent [Integer]
344
+ # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
276
345
  # @return [RedisQueuedLocks::Data, Hash<Symbol,Any>]
277
346
  # Format: {
278
347
  # ok: true/false,
@@ -287,7 +356,7 @@ class RedisQueuedLocks::Client
287
356
  #
288
357
  # @api public
289
358
  # @since 1.0.0
290
- # @version 1.5.0
359
+ # @version 1.6.0
291
360
  def unlock(
292
361
  lock_name,
293
362
  logger: config[:logger],
@@ -295,16 +364,22 @@ class RedisQueuedLocks::Client
295
364
  instrument: nil,
296
365
  log_sampling_enabled: config[:log_sampling_enabled],
297
366
  log_sampling_percent: config[:log_sampling_percent],
298
- log_sampler: config[:log_sampler]
367
+ log_sampler: config[:log_sampler],
368
+ instr_sampling_enabled: config[:instr_sampling_enabled],
369
+ instr_sampling_percent: config[:instr_sampling_percent],
370
+ instr_sampler: config[:instr_sampler]
299
371
  )
300
372
  RedisQueuedLocks::Acquier::ReleaseLock.release_lock(
301
373
  redis_client,
302
374
  lock_name,
303
- config[:instrumenter],
304
- config[:logger],
375
+ instrumenter,
376
+ logger,
305
377
  log_sampling_enabled,
306
378
  log_sampling_percent,
307
- log_sampler
379
+ log_sampler,
380
+ instr_sampling_enabled,
381
+ instr_sampling_percent,
382
+ instr_sampler
308
383
  )
309
384
  end
310
385
 
@@ -358,43 +433,47 @@ class RedisQueuedLocks::Client
358
433
  # @param lock_name [String]
359
434
  # @param milliseconds [Integer] How many milliseconds should be added.
360
435
  # @option logger [::Logger,#debug]
436
+ # @option instrumenter [#notify] See `config[:instrumenter]` docs for details.
437
+ # @option instrument [NilClass,Any]
361
438
  # @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
439
  # @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
440
  # @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
441
+ # @option instr_sampling_enabled [Boolean]
442
+ # @option instr_sampling_percent [Integer]
443
+ # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
375
444
  # @return [Hash<Symbol,Boolean|Symbol>]
376
445
  # - { ok: true, result: :ttl_extended }
377
446
  # - { ok: false, result: :async_expire_or_no_lock }
378
447
  #
379
448
  # @api public
380
449
  # @since 1.0.0
381
- # @version 1.5.0
450
+ # @version 1.6.0
382
451
  def extend_lock_ttl(
383
452
  lock_name,
384
453
  milliseconds,
385
454
  logger: config[:logger],
455
+ instrumenter: config[:instrumenter],
456
+ instrument: nil,
386
457
  log_sampling_enabled: config[:log_sampling_enabled],
387
458
  log_sampling_percent: config[:log_sampling_percent],
388
- log_sampler: config[:log_sampler]
459
+ log_sampler: config[:log_sampler],
460
+ instr_sampling_enabled: config[:instr_sampling_enabled],
461
+ instr_sampling_percent: config[:instr_sampling_percent],
462
+ instr_sampler: config[:instr_sampler]
389
463
  )
390
464
  RedisQueuedLocks::Acquier::ExtendLockTTL.extend_lock_ttl(
391
465
  redis_client,
392
466
  lock_name,
393
467
  milliseconds,
394
468
  logger,
469
+ instrumenter,
470
+ instrument,
395
471
  log_sampling_enabled,
396
472
  log_sampling_percent,
397
- log_sampler
473
+ log_sampler,
474
+ instr_sampling_enabled,
475
+ instr_sampling_percent,
476
+ instr_sampler
398
477
  )
399
478
  end
400
479
 
@@ -405,17 +484,20 @@ class RedisQueuedLocks::Client
405
484
  #
406
485
  # @option batch_size [Integer]
407
486
  # @option logger [::Logger,#debug]
408
- # @option instrumenter [#notify]
487
+ # @option instrumenter [#notify] See `config[:instrumenter]` docs for details.
409
488
  # @option instrument [NilClass,Any]
410
489
  # @option log_sampling_enabled [Boolean]
411
490
  # @option log_sampling_percent [Integer]
412
491
  # @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
492
+ # @option instr_sampling_enabled [Boolean]
493
+ # @option instr_sampling_percent [Integer]
494
+ # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
413
495
  # @return [RedisQueuedLocks::Data,Hash<Symbol,Boolean|Hash<Symbol,Numeric>>]
414
496
  # Example: { ok: true, result { rel_key_cnt: 100, rel_time: 0.01 } }
415
497
  #
416
498
  # @api public
417
499
  # @since 1.0.0
418
- # @version 1.5.0
500
+ # @version 1.6.0
419
501
  def clear_locks(
420
502
  batch_size: config[:lock_release_batch_size],
421
503
  logger: config[:logger],
@@ -423,7 +505,10 @@ class RedisQueuedLocks::Client
423
505
  instrument: nil,
424
506
  log_sampling_enabled: config[:log_sampling_enabled],
425
507
  log_sampling_percent: config[:log_sampling_percent],
426
- log_sampler: config[:log_sampler]
508
+ log_sampler: config[:log_sampler],
509
+ instr_sampling_enabled: config[:instr_sampling_enabled],
510
+ instr_sampling_percent: config[:instr_sampling_percent],
511
+ instr_sampler: config[:instr_sampler]
427
512
  )
428
513
  RedisQueuedLocks::Acquier::ReleaseAllLocks.release_all_locks(
429
514
  redis_client,
@@ -433,7 +518,10 @@ class RedisQueuedLocks::Client
433
518
  instrument,
434
519
  log_sampling_enabled,
435
520
  log_sampling_percent,
436
- log_sampler
521
+ log_sampler,
522
+ instr_sampling_enabled,
523
+ instr_sampling_percent,
524
+ instr_sampler
437
525
  )
438
526
  end
439
527
 
@@ -524,12 +612,15 @@ class RedisQueuedLocks::Client
524
612
  # @option log_sampling_enabled [Boolean]
525
613
  # @option log_sampling_percent [Integer]
526
614
  # @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
615
+ # @option instr_sampling_enabled [Boolean]
616
+ # @option instr_sampling_percent [Integer]
617
+ # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
527
618
  # @return [Hash<Symbol,Boolean|Hash<Symbol,Set<String>>>]
528
619
  # Format: { ok: true, result: { processed_queus: Set<String> } }
529
620
  #
530
621
  # @api public
531
622
  # @since 1.0.0
532
- # @version 1.5.0
623
+ # @version 1.6.0
533
624
  def clear_dead_requests(
534
625
  dead_ttl: config[:dead_request_ttl],
535
626
  scan_size: config[:lock_release_batch_size],
@@ -538,7 +629,10 @@ class RedisQueuedLocks::Client
538
629
  instrument: nil,
539
630
  log_sampling_enabled: config[:log_sampling_enabled],
540
631
  log_sampling_percent: config[:log_sampling_percent],
541
- log_sampler: config[:log_sampler]
632
+ log_sampler: config[:log_sampler],
633
+ instr_sampling_enabled: config[:instr_sampling_enabled],
634
+ instr_sampling_percent: config[:instr_sampling_percent],
635
+ instr_sampler: config[:instr_sampler]
542
636
  )
543
637
  RedisQueuedLocks::Acquier::ClearDeadRequests.clear_dead_requests(
544
638
  redis_client,
@@ -549,7 +643,10 @@ class RedisQueuedLocks::Client
549
643
  instrument,
550
644
  log_sampling_enabled,
551
645
  log_sampling_percent,
552
- log_sampler
646
+ log_sampler,
647
+ instr_sampling_enabled,
648
+ instr_sampling_percent,
649
+ instr_sampler
553
650
  )
554
651
  end
555
652
  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 private
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 private
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(0..100)
25
+ sampling_percent >= SecureRandom.rand(SAMPLING_PERCENT_RANGE)
19
26
  end
20
27
  end
21
28
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api public
4
4
  # @since 1.0.0
5
+ # @version 1.5.0
5
6
  module RedisQueuedLocks::Logging
6
7
  require_relative 'logging/void_logger'
7
8
  require_relative 'logging/sampler'
@@ -2,7 +2,6 @@
2
2
 
3
3
  # @api private
4
4
  # @since 1.0.0
5
- # @version 1.5.0
6
5
  module RedisQueuedLocks::Utilities
7
6
  module_function
8
7
 
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 1.5.0
9
- VERSION = '1.5.0'
8
+ # @version 1.7.0
9
+ VERSION = '1.7.0'
10
10
  end
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -10,9 +10,29 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['Rustam Ibragimov']
11
11
  spec.email = ['iamdaiver@gmail.com']
12
12
 
13
- spec.summary = 'Queued distributed locks based on Redis.'
14
- spec.description = 'Distributed locks with "lock acquisition queue" ' \
15
- 'capabilities based on the Redis Database.'
13
+ spec.summary =
14
+ 'Distributed locks with "prioritized lock acquisition queue" ' \
15
+ 'capabilities based on the Redis Database.'
16
+
17
+ spec.description =
18
+ 'Distributed locks with "prioritized lock acquisition queue" capabilities ' \
19
+ 'based on the Redis Database. ' \
20
+ # ---
21
+ 'Each lock request is put into the request queue ' \
22
+ "(each lock is hosted by it's own queue separately from other queues) and processed " \
23
+ 'in order of their priority (FIFO). ' \
24
+ # ---
25
+ 'Each lock request lives some period of time (RTTL) ' \
26
+ '(with requeue capabilities) which guarantees the request queue will never be stacked. ' \
27
+ # ---
28
+ 'In addition to the classic `queued` (FIFO) strategy RQL supports ' \
29
+ '`random` (RANDOM) lock obtaining strategy when any acquirer from the lock queue ' \
30
+ 'can obtain the lock regardless the position in the queue. ' \
31
+ # ---
32
+ 'Provides flexible invocation flow, parametrized limits ' \
33
+ '(lock request ttl, lock ttl, queue ttl, lock attempts limit, fast failing, etc), ' \
34
+ 'logging and instrumentation.'
35
+
16
36
  spec.homepage = 'https://github.com/0exp/redis_queued_locks'
17
37
  spec.license = 'MIT'
18
38
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_queued_locks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-23 00:00:00.000000000 Z
11
+ date: 2024-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.28'
41
- description: Distributed locks with "lock acquisition queue" capabilities based on
42
- the Redis Database.
41
+ description: 'Distributed locks with "prioritized lock acquisition queue" capabilities
42
+ based on the Redis Database. '
43
43
  email:
44
44
  - iamdaiver@gmail.com
45
45
  executables: []
@@ -58,9 +58,15 @@ files:
58
58
  - lib/redis_queued_locks/acquier.rb
59
59
  - lib/redis_queued_locks/acquier/acquire_lock.rb
60
60
  - lib/redis_queued_locks/acquier/acquire_lock/delay_execution.rb
61
+ - lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue.rb
62
+ - lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue/log_visitor.rb
63
+ - lib/redis_queued_locks/acquier/acquire_lock/instr_visitor.rb
64
+ - lib/redis_queued_locks/acquier/acquire_lock/log_visitor.rb
61
65
  - lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb
66
+ - lib/redis_queued_locks/acquier/acquire_lock/try_to_lock/log_visitor.rb
62
67
  - lib/redis_queued_locks/acquier/acquire_lock/with_acq_timeout.rb
63
68
  - lib/redis_queued_locks/acquier/acquire_lock/yield_expire.rb
69
+ - lib/redis_queued_locks/acquier/acquire_lock/yield_expire/log_visitor.rb
64
70
  - lib/redis_queued_locks/acquier/clear_dead_requests.rb
65
71
  - lib/redis_queued_locks/acquier/extend_lock_ttl.rb
66
72
  - lib/redis_queued_locks/acquier/is_locked.rb
@@ -79,6 +85,7 @@ files:
79
85
  - lib/redis_queued_locks/errors.rb
80
86
  - lib/redis_queued_locks/instrument.rb
81
87
  - lib/redis_queued_locks/instrument/active_support.rb
88
+ - lib/redis_queued_locks/instrument/sampler.rb
82
89
  - lib/redis_queued_locks/instrument/void_notifier.rb
83
90
  - lib/redis_queued_locks/logging.rb
84
91
  - lib/redis_queued_locks/logging/sampler.rb
@@ -86,6 +93,7 @@ files:
86
93
  - lib/redis_queued_locks/resource.rb
87
94
  - lib/redis_queued_locks/utilities.rb
88
95
  - lib/redis_queued_locks/version.rb
96
+ - lib/redis_queued_locks/watcher.rb
89
97
  - redis_queued_locks.gemspec
90
98
  homepage: https://github.com/0exp/redis_queued_locks
91
99
  licenses:
@@ -109,8 +117,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
117
  - !ruby/object:Gem::Version
110
118
  version: '0'
111
119
  requirements: []
112
- rubygems_version: 3.5.1
120
+ rubygems_version: 3.3.7
113
121
  signing_key:
114
122
  specification_version: 4
115
- summary: Queued distributed locks based on Redis.
123
+ summary: Distributed locks with "prioritized lock acquisition queue" capabilities
124
+ based on the Redis Database.
116
125
  test_files: []