redis_queued_locks 1.0.0 → 1.2.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/README.md +84 -17
  4. data/lib/redis_queued_locks/acquier/acquire_lock/delay_execution.rb +2 -2
  5. data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb +4 -4
  6. data/lib/redis_queued_locks/acquier/acquire_lock/with_acq_timeout.rb +2 -2
  7. data/lib/redis_queued_locks/acquier/acquire_lock/yield_with_expire.rb +4 -4
  8. data/lib/redis_queued_locks/acquier/acquire_lock.rb +9 -9
  9. data/lib/redis_queued_locks/acquier/clear_dead_requests.rb +3 -3
  10. data/lib/redis_queued_locks/acquier/extend_lock_ttl.rb +3 -3
  11. data/lib/redis_queued_locks/acquier/is_locked.rb +2 -2
  12. data/lib/redis_queued_locks/acquier/is_queued.rb +2 -2
  13. data/lib/redis_queued_locks/acquier/keys.rb +2 -2
  14. data/lib/redis_queued_locks/acquier/lock_info.rb +2 -2
  15. data/lib/redis_queued_locks/acquier/locks.rb +4 -4
  16. data/lib/redis_queued_locks/acquier/queue_info.rb +2 -2
  17. data/lib/redis_queued_locks/acquier/queues.rb +4 -4
  18. data/lib/redis_queued_locks/acquier/release_all_locks.rb +4 -4
  19. data/lib/redis_queued_locks/acquier/release_lock.rb +4 -4
  20. data/lib/redis_queued_locks/acquier.rb +1 -1
  21. data/lib/redis_queued_locks/client.rb +27 -25
  22. data/lib/redis_queued_locks/debugger/interface.rb +4 -4
  23. data/lib/redis_queued_locks/debugger.rb +8 -8
  24. data/lib/redis_queued_locks/errors.rb +6 -6
  25. data/lib/redis_queued_locks/instrument/active_support.rb +2 -2
  26. data/lib/redis_queued_locks/instrument/void_notifier.rb +2 -2
  27. data/lib/redis_queued_locks/instrument.rb +2 -2
  28. data/lib/redis_queued_locks/logging/void_logger.rb +10 -10
  29. data/lib/redis_queued_locks/logging.rb +10 -3
  30. data/lib/redis_queued_locks/resource.rb +16 -16
  31. data/lib/redis_queued_locks/utilities.rb +2 -2
  32. data/lib/redis_queued_locks/version.rb +2 -2
  33. data/lib/redis_queued_locks.rb +2 -2
  34. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83f1a77fc07b776195720c2f06a7117baa22ea7f68be06120d3fe7befe26db84
4
- data.tar.gz: 4a06cb4f59afb485331513ab01172c2836f07702bd79fdc85c95efaa459a2597
3
+ metadata.gz: 6b1c8d60f41d2dc4f3eda798efa02a4764b877e6666e8babd7cf1a7827a4b288
4
+ data.tar.gz: 983e142251b344055013aa2aac2965ad542d44f5c8f81ac410f97cdef7b216b3
5
5
  SHA512:
6
- metadata.gz: ebae6ceee85253f767b0de53b70a69f00590e91bbcdb6c86860c35a00d736f59593f924eaccb13b593def1f9b504f338f786a2eeb59f9dcd4a596c9d70f2f348
7
- data.tar.gz: 5e6e97c4645df750d618c778caccd80fa3eab1491e141b238e5e4c1ed15f59c72871c00f10d38269f33ada195b96ed5b407a62cc52d2543a169b150d2150c770
6
+ metadata.gz: 88b91754923e546767d03999601fb98bd04b00fb426e50691e2fd4ce1bf13e345c19179b534660a639d0a885d1fdad4db94ffda0fa4383d7d9dcf53981ca481b
7
+ data.tar.gz: f9368018c66eee962a9dd6be1b38efe7bb4359cdfb262956f4e2e43622aaf747b67b4aa6b7a9bcda6c8449e011cb1c2954d5a6e5324afdbfbb8eea0ca96085b0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.2.0] - 2024-04-27
4
+ ### Added
5
+ - Documentation updates;
6
+ - Logging: support for `semantic_logger` loggers (see: https://logger.rocketjob.io/) (https://github.com/reidmorrison/semantic_logger)
7
+
8
+ ## [1.1.0] - 2024-04-01
9
+ ### Added
10
+ - Documentation updates:
11
+ - more `#lock` examples;
12
+ - added missing docs for `config.dead_request_ttl`;
13
+ - some minor updates;
14
+ ### Changed
15
+ - `#clear_dead_requests`: `:scan_size` is equal to `config[:lock_release_batch_size]` now (instead of to `config[:key_extraction_batch_size]`), cuz `#clear_dead_requests` works with lock releasing;
16
+
3
17
  ## [1.0.0] - 2024-04-01
4
18
  - First Major Release;
5
19
 
@@ -185,7 +199,7 @@
185
199
  ### Changed
186
200
  - The lock acquier identifier (`acq_id`) now includes the fiber id, the ractor id and an unique per-process
187
201
  10 byte string. It is added in order to prevent collisions between different processes/pods
188
- that will have the same procjet id / thread id identifiers (cuz it is an object_id integers) that can lead
202
+ that will have the same process id / thread id identifiers (cuz it is an object_id integers) that can lead
189
203
  to the same position with the same `acq_id` for different processes/pods in the lock request queue.
190
204
 
191
205
  ## [0.0.8] - 2024-02-27
data/README.md CHANGED
@@ -150,15 +150,21 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
150
150
  config.is_timed_by_default = false
151
151
 
152
152
  # (default: 100)
153
- # - how many items will be released at a time in RedisQueuedLocks::Client#clear_locks logic (uses SCAN);
154
- # - affects the performancs of your Redis and Ruby Application (configure thoughtfully);
153
+ # - how many items will be released at a time in #clear_locks and in #clear_dead_requests (uses SCAN);
154
+ # - affects the performance of your Redis and Ruby Application (configure thoughtfully);
155
155
  config.lock_release_batch_size = 100
156
156
 
157
157
  # (default: 500)
158
- # - how many items should be extracted from redis during the #locks, #queues and #keys operations (uses SCAN);
158
+ # - how many items should be extracted from redis during the #locks, #queues, #keys
159
+ # #locks_info, and #queues_info operations (uses SCAN);
159
160
  # - affects the performance of your Redis and Ruby Application (configure thoughtfully;)
160
161
  config.key_extraction_batch_size = 500
161
162
 
163
+ # (default: 1 day)
164
+ # - the default period of time (in milliseconds) after which a lock request is considered dead;
165
+ # - used for `#clear_dead_requests` as default vaule of `:dead_ttl` option;
166
+ config.dead_request_ttl = (1 * 24 * 60 * 60 * 1000) # one day in milliseconds
167
+
162
168
  # (default: RedisQueuedLocks::Instrument::VoidNotifier)
163
169
  # - instrumentation layer;
164
170
  # - you can provde your own instrumenter with `#notify(event, payload = {})`
@@ -245,7 +251,7 @@ def lock(
245
251
  ttl: config[:default_lock_ttl],
246
252
  queue_ttl: config[:default_queue_ttl],
247
253
  timeout: config[:try_to_lock_timeout],
248
- timed: false,
254
+ timed: config[:is_timed_by_default],
249
255
  retry_count: config[:retry_count],
250
256
  retry_delay: config[:retry_delay],
251
257
  retry_jitter: config[:retry_jitter],
@@ -318,10 +324,12 @@ def lock(
318
324
  - should be logged the each try of lock acquiring (a lot of logs can be generated depending on your retry configurations);
319
325
  - pre-configured in `config[:log_lock_try]`;
320
326
  - `false` by default;
321
- - `block` - `[Block]`
327
+ - `block` - (optional) `[Block]`
322
328
  - A block of code that should be executed after the successfully acquired lock.
323
329
  - If block is **passed** the obtained lock will be released after the block execution or it's ttl (what will happen first);
324
330
  - If block is **not passed** the obtained lock will be released after it's ttl;
331
+ - If you want the block to have a TTL too and this TTL to be the same as TTL of the lock
332
+ use `timed: true` option (`rql.lock("my_lock", timed: true, ttl: 5_000) { ... }`)
325
333
 
326
334
  Return value:
327
335
 
@@ -429,6 +437,61 @@ rql.lock("my_lock", ttl: 6_500) # blocks execution until the lock is obtained
429
437
  puts "Let's go" # will be called immediately after the lock is obtained
430
438
  ```
431
439
 
440
+ - add custom metadata to the lock (via `:meta` option):
441
+
442
+ ```ruby
443
+ rql.lock("my_lock", ttl: 123456, meta: { "some" => "data", key: 123.456 })
444
+
445
+ rql.lock_info("my_lock")
446
+ # =>
447
+ {
448
+ "lock_key" => "rql:lock:my_lock",
449
+ "acq_id" => "rql:acq:123/456/567/678/374dd74324",
450
+ "ts" => 123456789,
451
+ "ini_ttl" => 123456,
452
+ "rem_ttl" => 123440,
453
+ "some" => "data",
454
+ "key" => "123.456" # NOTE: returned as a raw string directly from Redis
455
+ }
456
+ ```
457
+
458
+ - (`:queue_ttl`) setting a short limit of time to the lock request queue position (if a process fails to acquire
459
+ the lock within this period of time (and before timeout/retry_count limits occurs of course) -
460
+ it's lock request will be moved to the end of queue):
461
+
462
+ ```ruby
463
+ rql.lock("my_lock", queue_ttl: 5, timeout: 10_000, retry_count: nil)
464
+ # "queue_ttl: 5": 5 seconds time slot before the lock request moves to the end of queue;
465
+ # "timeout" and "retry_count" is used as "endless lock try attempts" example to show the lock queue behavior;
466
+
467
+ # lock queue: =>
468
+ [
469
+ "rql:acq:123/456/567/676/374dd74324",
470
+ "rql:acq:123/456/567/677/374dd74322", # <- long living lock
471
+ "rql:acq:123/456/567/679/374dd74321",
472
+ "rql:acq:123/456/567/683/374dd74322", # <== we are here
473
+ "rql:acq:123/456/567/685/374dd74329", # some other waiting process
474
+ ]
475
+
476
+ # ... some period of time (2 seconds later)
477
+ # lock queue: =>
478
+ [
479
+ "rql:acq:123/456/567/677/374dd74322", # <- long living lock
480
+ "rql:acq:123/456/567/679/374dd74321",
481
+ "rql:acq:123/456/567/683/374dd74322", # <== we are here
482
+ "rql:acq:123/456/567/685/374dd74329", # some other waiting process
483
+ ]
484
+
485
+ # ... some period of time (3 seconds later)
486
+ # ... queue_ttl time limit is reached
487
+ # lock queue: =>
488
+ [
489
+ "rql:acq:123/456/567/685/374dd74329", # some other waiting process
490
+ "rql:acq:123/456/567/683/374dd74322", # <== we are here (moved to the end of the queue)
491
+ ]
492
+
493
+ ```
494
+
432
495
  ---
433
496
 
434
497
  #### #lock! - exceptional lock obtaining
@@ -539,9 +602,9 @@ rql.queue_info("your_lock_name")
539
602
  {
540
603
  "lock_queue" => "rql:lock_queue:your_lock_name",
541
604
  "queue" => [
542
- { "acq_id" => "rql:acq:123/456/567/678/fa76df9cc2", "score" => 1},
543
- { "acq_id" => "rql:acq:123/567/456/679/c7bfcaf4f9", "score" => 2},
544
- { "acq_id" => "rql:acq:555/329/523/127/7329553b11", "score" => 3},
605
+ { "acq_id" => "rql:acq:123/456/567/678/fa76df9cc2", "score" => 1711606640.540842},
606
+ { "acq_id" => "rql:acq:123/567/456/679/c7bfcaf4f9", "score" => 1711606640.540906},
607
+ { "acq_id" => "rql:acq:555/329/523/127/7329553b11", "score" => 1711606640.540963},
545
608
  # ...etc
546
609
  ]
547
610
  }
@@ -563,6 +626,8 @@ rql.locked?("your_lock_name") # => true/false
563
626
 
564
627
  #### #queued?
565
628
 
629
+ <sup>\[[back to top](#usage)\]</sup>
630
+
566
631
  - is the lock queued for obtain / has requests for obtain?
567
632
 
568
633
  ```ruby
@@ -611,7 +676,7 @@ rql.unlock("your_lock_name")
611
676
  result: {
612
677
  rel_time: 0.02, # time spent to lock release (in seconds)
613
678
  rel_key: "rql:lock:your_lock_name", # released lock key
614
- rel_queue: "rql:lock_queue:your_lock_name" # released lock key queue
679
+ rel_queue: "rql:lock_queue:your_lock_name", # released lock key queue
615
680
  queue_res: :released, # or :nothing_to_release
616
681
  lock_res: :released # or :nothing_to_release
617
682
  }
@@ -638,12 +703,11 @@ rql.unlock("your_lock_name")
638
703
  - pre-configured value in `config[:isntrumenter]`;
639
704
  - `:instrument` - (optional) `[NilClass,Any]`
640
705
  - custom instrumentation data wich will be passed to the instrumenter's payload with `:instrument` key;
641
-
642
706
  - returns:
643
- - `[Hash<Symbol,Numeric>]` - Format: `{ ok: true, result: Hash<Symbol,Numeric> }`;
644
- - result data:
645
- - `:rel_time` - `Numeric` - time spent to release all locks and related queus;
646
- - `:rel_key_cnt` - `Integer` - the number of released Redis keys (queues+locks);
707
+ - `[Hash<Symbol,Numeric>]` - Format: `{ ok: true, result: Hash<Symbol,Numeric> }`;
708
+ - result data:
709
+ - `:rel_time` - `Numeric` - time spent to release all locks and related queus;
710
+ - `:rel_key_cnt` - `Integer` - the number of released Redis keys (queues+locks);
647
711
 
648
712
  ```ruby
649
713
  rql.clear_locks
@@ -675,13 +739,14 @@ rql.clear_locks
675
739
  - custom logger object;
676
740
  - pre-configured in `config[:logger]`;
677
741
  - returns `{ ok: true, result: :ttl_extended }` when ttl is extended;
678
- - returns `{ ok: false, result: :async_expire_or_no_lock }` when lock not found or lock is expired during
742
+ - returns `{ ok: false, result: :async_expire_or_no_lock }` when a lock not found or a lock is already expired during
679
743
  some steps of invocation (see **Important** section below);
680
744
  - **Important**:
681
745
  - the method is non-atomic cuz redis does not provide an atomic function for TTL/PTTL extension;
682
746
  - the method consists of two commands:
683
747
  - (1) read current pttl;
684
748
  - (2) set new ttl that is calculated as "current pttl + additional milliseconds";
749
+ - the method uses Redis'es **CAS** (check-and-set) behavior;
685
750
  - what can happen during these steps:
686
751
  - lock is expired between commands or before the first command;
687
752
  - lock is expired before the second command;
@@ -884,7 +949,7 @@ Accepts:
884
949
  - has a preconfigured value in `config[:dead_request_ttl]` (1 day by default);
885
950
  - `:sacn_size` - (optional) `[Integer]`
886
951
  - the batch of scanned keys for Redis'es SCAN command;
887
- - has a preconfigured valie in `config[:key_extraction_batch_size]`;
952
+ - has a preconfigured valie in `config[:lock_release_batch_size]`;
888
953
  - `:logger` - (optional) `[::Logger,#debug]`
889
954
  - custom logger object;
890
955
  - pre-configured in `config[:logger]`;
@@ -970,7 +1035,7 @@ By default `RedisQueuedLocks::Client` is configured with the void notifier (whic
970
1035
 
971
1036
  ### Instrumentation Events
972
1037
 
973
- <sup>\[[back to top](#instrumentation-events)\]</sup>
1038
+ <sup>\[[back to top](#instrumentation)\]</sup>
974
1039
 
975
1040
  List of instrumentation events
976
1041
 
@@ -1028,6 +1093,7 @@ Detalized event semantics and payload structure:
1028
1093
  <sup>\[[back to top](#table-of-contents)\]</sup>
1029
1094
 
1030
1095
  - **strict redlock algorithm support** (support for many `RedisClient` instances);
1096
+ - deadlock detection (with some options for auto-resolving);
1031
1097
  - Semantic Error objects for unexpected Redis errors;
1032
1098
  - better specs with 100% test coverage (total rework);
1033
1099
  - (non-`timed` locks): per-ruby-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
@@ -1035,6 +1101,7 @@ Detalized event semantics and payload structure:
1035
1101
  whose ttl may expire before the block execution completes). It makes sense for non-`timed` locks *only*;
1036
1102
  - lock request prioritization;
1037
1103
  - support for LIFO strategy;
1104
+ - support for Random Access strategy;
1038
1105
  - more structured logging (separated docs);
1039
1106
  - `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
1040
1107
  - better code stylization (+ some refactorings);
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::AcquireLock::DelayExecution
6
6
  # Sleep with random time-shifting (it is necessary for empty lock-acquirement time slots).
7
7
  #
@@ -10,7 +10,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::DelayExecution
10
10
  # @return [void]
11
11
  #
12
12
  # @api private
13
- # @since 0.1.0
13
+ # @since 1.0.0
14
14
  def delay_execution(retry_delay, retry_jitter)
15
15
  delay = (retry_delay + rand(retry_jitter)).to_f / 1_000
16
16
  sleep(delay)
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  # rubocop:disable Metrics/ModuleLength, Metrics/BlockNesting
6
6
  module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
7
- # @since 0.1.0
7
+ # @since 1.0.0
8
8
  extend RedisQueuedLocks::Utilities
9
9
 
10
10
  # @param redis [RedisClient]
@@ -21,7 +21,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
21
21
  # @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Symbol|Hash<Symbol,Any> }
22
22
  #
23
23
  # @api private
24
- # @since 0.1.0
24
+ # @since 1.0.0
25
25
  # rubocop:disable Metrics/MethodLength
26
26
  def try_to_lock(
27
27
  redis,
@@ -259,7 +259,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
259
259
  # @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Any }
260
260
  #
261
261
  # @api private
262
- # @since 0.1.0
262
+ # @since 1.0.0
263
263
  def dequeue_from_lock_queue(redis, logger, lock_key, lock_key_queue, queue_ttl, acquier_id)
264
264
  result = redis.call('ZREM', lock_key_queue, acquier_id)
265
265
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout
6
6
  # @param timeout [NilClass,Integer]
7
7
  # Time period after which the logic will fail with timeout error.
@@ -14,7 +14,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout
14
14
  # @return [Any]
15
15
  #
16
16
  # @api private
17
- # @since 0.1.0
17
+ # @since 1.0.0
18
18
  def with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: nil, &block)
19
19
  ::Timeout.timeout(timeout, &block)
20
20
  rescue ::Timeout::Error
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
6
- # @since 0.1.0
6
+ # @since 1.0.0
7
7
  extend RedisQueuedLocks::Utilities
8
8
 
9
9
  # @param redis [RedisClient] Redis connection manager.
@@ -18,7 +18,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
18
18
  # @return [Any,NilClass] nil is returned no block parametr is provided.
19
19
  #
20
20
  # @api private
21
- # @since 0.1.0
21
+ # @since 1.0.0
22
22
  def yield_with_expire(
23
23
  redis,
24
24
  logger,
@@ -59,7 +59,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
59
59
  # @return [Any]
60
60
  #
61
61
  # @api private
62
- # @since 0.1.0
62
+ # @since 1.0.0
63
63
  def yield_with_timeout(timeout, lock_key, lock_ttl, &block)
64
64
  ::Timeout.timeout(timeout, &block)
65
65
  rescue ::Timeout::Error
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  # rubocop:disable Metrics/ModuleLength
6
6
  # rubocop:disable Metrics/MethodLength
7
7
  # rubocop:disable Metrics/ClassLength
@@ -12,21 +12,21 @@ module RedisQueuedLocks::Acquier::AcquireLock
12
12
  require_relative 'acquire_lock/yield_with_expire'
13
13
  require_relative 'acquire_lock/try_to_lock'
14
14
 
15
- # @since 0.1.0
15
+ # @since 1.0.0
16
16
  extend TryToLock
17
- # @since 0.1.0
17
+ # @since 1.0.0
18
18
  extend DelayExecution
19
- # @since 0.1.0
19
+ # @since 1.0.0
20
20
  extend YieldWithExpire
21
- # @since 0.1.0
21
+ # @since 1.0.0
22
22
  extend WithAcqTimeout
23
- # @since 0.1.0
23
+ # @since 1.0.0
24
24
  extend RedisQueuedLocks::Utilities
25
25
 
26
26
  # @return [Integer] Redis time error (in milliseconds).
27
27
  #
28
28
  # @api private
29
- # @since 0.1.0
29
+ # @since 1.0.0
30
30
  REDIS_TIMESHIFT_ERROR = 2
31
31
 
32
32
  class << self
@@ -87,7 +87,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
87
87
  # - If block is given the result of block's yeld will be returned.
88
88
  #
89
89
  # @api private
90
- # @since 0.1.0
90
+ # @since 1.0.0
91
91
  def acquire_lock(
92
92
  redis,
93
93
  lock_name,
@@ -186,7 +186,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
186
186
  with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
187
187
  acq_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
188
188
 
189
- # Step 2.1: caclically try to obtain the lock
189
+ # Step 2.1: cyclically try to obtain the lock
190
190
  while acq_process[:should_try]
191
191
  run_non_critical do
192
192
  logger.debug do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::ClearDeadRequests
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -13,7 +13,7 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests
13
13
  # @return [Hash<Symbol,Boolean|Hash<Symbol,Set<String>>>]
14
14
  #
15
15
  # @api private
16
- # @since 0.1.0
16
+ # @since 1.0.0
17
17
  def clear_dead_requests(redis_client, scan_size, dead_ttl, logger, instrumenter, instrument)
18
18
  dead_score = RedisQueuedLocks::Resource.acquier_dead_score(dead_ttl / 1000.0)
19
19
 
@@ -39,7 +39,7 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests
39
39
  # @return [Enumerator]
40
40
  #
41
41
  # @api private
42
- # @since 0.1.0
42
+ # @since 1.0.0
43
43
  def each_lock_queue(redis_client, scan_size, &block)
44
44
  redis_client.scan(
45
45
  'MATCH',
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::ExtendLockTTL
6
6
  # @return [String]
7
7
  #
8
8
  # @api private
9
- # @since 0.1.0
9
+ # @since 1.0.0
10
10
  EXTEND_LOCK_PTTL = <<~LUA_SCRIPT.strip.tr("\n", '').freeze
11
11
  local new_lock_pttl = redis.call("PTTL", KEYS[1]) + ARGV[1];
12
12
  return redis.call("PEXPIRE", KEYS[1], new_lock_pttl);
@@ -20,7 +20,7 @@ module RedisQueuedLocks::Acquier::ExtendLockTTL
20
20
  # @return [Hash<Symbol,Boolean|Symbol>]
21
21
  #
22
22
  # @api private
23
- # @since 0.1.0
23
+ # @since 1.0.0
24
24
  def extend_lock_ttl(redis_client, lock_name, milliseconds, logger)
25
25
  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
26
26
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::IsLocked
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Acquier::IsLocked
9
9
  # @return [Boolean]
10
10
  #
11
11
  # @api private
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def locked?(redis_client, lock_name)
14
14
  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
15
15
  redis_client.call('EXISTS', lock_key) == 1
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::IsQueued
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Acquier::IsQueued
9
9
  # @return [Boolean]
10
10
  #
11
11
  # @api private
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def queued?(redis_client, lock_name)
14
14
  lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
15
15
  redis_client.call('EXISTS', lock_key_queue) == 1
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::Keys
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Acquier::Keys
9
9
  # @return [Array<String>]
10
10
  #
11
11
  # @api private
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def keys(redis_client, scan_size:)
14
14
  Set.new.tap do |keys|
15
15
  redis_client.scan(
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::LockInfo
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -17,7 +17,7 @@ module RedisQueuedLocks::Acquier::LockInfo
17
17
  # }
18
18
  #
19
19
  # @api private
20
- # @since 0.1.0
20
+ # @since 1.0.0
21
21
  def lock_info(redis_client, lock_name)
22
22
  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
23
23
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::Locks
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -10,7 +10,7 @@ module RedisQueuedLocks::Acquier::Locks
10
10
  # @return [Set<String>,Set<Hash<Symbol,Any>>]
11
11
  #
12
12
  # @api private
13
- # @since 0.1.0
13
+ # @since 1.0.0
14
14
  def locks(redis_client, scan_size:, with_info:)
15
15
  redis_client.with do |rconn|
16
16
  lock_keys = scan_locks(rconn, scan_size)
@@ -25,7 +25,7 @@ module RedisQueuedLocks::Acquier::Locks
25
25
  # @return [Set<String>]
26
26
  #
27
27
  # @api private
28
- # @since 0.1.0
28
+ # @since 1.0.0
29
29
  def scan_locks(redis_client, scan_size)
30
30
  Set.new.tap do |lock_keys|
31
31
  redis_client.scan(
@@ -44,7 +44,7 @@ module RedisQueuedLocks::Acquier::Locks
44
44
  # @return [Set<Hash<Symbol,Any>>]
45
45
  #
46
46
  # @api private
47
- # @since 0.1.0
47
+ # @since 1.0.0
48
48
  # rubocop:disable Metrics/MethodLength
49
49
  def extract_locks_info(redis_client, lock_keys)
50
50
  # TODO: refactor with RedisQueuedLocks::Acquier::LockInfo
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::QueueInfo
6
6
  class << self
7
7
  # Returns an information about the required lock queue by the lock name. The result
@@ -23,7 +23,7 @@ module RedisQueuedLocks::Acquier::QueueInfo
23
23
  # }
24
24
  #
25
25
  # @api private
26
- # @since 0.1.0
26
+ # @since 1.0.0
27
27
  def queue_info(redis_client, lock_name)
28
28
  lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
29
29
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::Queues
6
6
  class << self
7
7
  # @param redis_client [RedisClient]
@@ -10,7 +10,7 @@ module RedisQueuedLocks::Acquier::Queues
10
10
  # @return [Set<String>,Set<Hash<Symbol,Any>>]
11
11
  #
12
12
  # @api private
13
- # @since 0.1.0
13
+ # @since 1.0.0
14
14
  def queues(redis_client, scan_size:, with_info:)
15
15
  redis_client.with do |rconn|
16
16
  lock_queues = scan_queues(rconn, scan_size)
@@ -25,7 +25,7 @@ module RedisQueuedLocks::Acquier::Queues
25
25
  # @return [Set<String>]
26
26
  #
27
27
  # @api private
28
- # @since 0.1.0
28
+ # @since 1.0.0
29
29
  def scan_queues(redis_client, scan_size)
30
30
  Set.new.tap do |lock_queues|
31
31
  redis_client.scan(
@@ -44,7 +44,7 @@ module RedisQueuedLocks::Acquier::Queues
44
44
  # @return [Set<Hash<Symbol,Any>>]
45
45
  #
46
46
  # @api private
47
- # @since 0.1.0
47
+ # @since 1.0.0
48
48
  def extract_queues_info(redis_client, lock_queues)
49
49
  # TODO: refactor with RedisQueuedLocks::Acquier::QueueInfo
50
50
  Set.new.tap do |seeded_queues|
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::ReleaseAllLocks
6
- # @since 0.1.0
6
+ # @since 1.0.0
7
7
  extend RedisQueuedLocks::Utilities
8
8
 
9
9
  class << self
@@ -27,7 +27,7 @@ module RedisQueuedLocks::Acquier::ReleaseAllLocks
27
27
  # Format: { ok: true, result: Hash<Symbol,Numeric> }
28
28
  #
29
29
  # @api private
30
- # @since 0.1.0
30
+ # @since 1.0.0
31
31
  def release_all_locks(redis, batch_size, logger, instrumenter, instrument)
32
32
  rel_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
33
33
  fully_release_all_locks(redis, batch_size) => { ok:, result: }
@@ -59,7 +59,7 @@ module RedisQueuedLocks::Acquier::ReleaseAllLocks
59
59
  # - Exmaple: { ok: true, result: { rel_key_cnt: 12345 } }
60
60
  #
61
61
  # @api private
62
- # @since 0.1.0
62
+ # @since 1.0.0
63
63
  def fully_release_all_locks(redis, batch_size)
64
64
  result = redis.with do |rconn|
65
65
  rconn.pipelined do |pipeline|
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::ReleaseLock
6
- # @since 0.1.0
6
+ # @since 1.0.0
7
7
  extend RedisQueuedLocks::Utilities
8
8
 
9
9
  class << self
@@ -27,7 +27,7 @@ module RedisQueuedLocks::Acquier::ReleaseLock
27
27
  # Format: { ok: true/false, result: Hash<Symbol,Numeric|String|Symbol> }
28
28
  #
29
29
  # @api private
30
- # @since 0.1.0
30
+ # @since 1.0.0
31
31
  def release_lock(redis, lock_name, instrumenter, logger)
32
32
  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
33
33
  lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
@@ -76,7 +76,7 @@ module RedisQueuedLocks::Acquier::ReleaseLock
76
76
  # }
77
77
  #
78
78
  # @api private
79
- # @since 0.1.0
79
+ # @since 1.0.0
80
80
  def fully_release_lock(redis, lock_key, lock_key_queue)
81
81
  result = redis.with do |rconn|
82
82
  rconn.multi do |transact|