redis_queued_locks 1.1.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 +7 -3
  3. data/README.md +58 -15
  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 +8 -8
  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 +21 -20
  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 +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b175564df436902d56e07a376f0257118eced8d7c81dbb81837e63cdef74938
4
- data.tar.gz: f88d3e83045cb4dd4dcd10b12744399ce45d3b99a84f6ca492d801a678db55f0
3
+ metadata.gz: 6b1c8d60f41d2dc4f3eda798efa02a4764b877e6666e8babd7cf1a7827a4b288
4
+ data.tar.gz: 983e142251b344055013aa2aac2965ad542d44f5c8f81ac410f97cdef7b216b3
5
5
  SHA512:
6
- metadata.gz: ae486564a408bc9039d6b09f3fe08ba37e733bae902ec2c3f55eae84b22a05e6c6f31bc9ceafc5ee78a10ae34dfdc0b3e7dcbfb09a41f74795ed29dce823a6bc
7
- data.tar.gz: ba40ab572fb1863b0bcddee6536385d19e3b3c7c9df07b2e2d71d74ad740eccb05a18847222be70bf6796596ce2b93266dbf462dccab294c6200a4441ca1f1a7
6
+ metadata.gz: 88b91754923e546767d03999601fb98bd04b00fb426e50691e2fd4ce1bf13e345c19179b534660a639d0a885d1fdad4db94ffda0fa4383d7d9dcf53981ca481b
7
+ data.tar.gz: f9368018c66eee962a9dd6be1b38efe7bb4359cdfb262956f4e2e43622aaf747b67b4aa6b7a9bcda6c8449e011cb1c2954d5a6e5324afdbfbb8eea0ca96085b0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
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
+
3
8
  ## [1.1.0] - 2024-04-01
4
9
  ### Added
5
10
  - Documentation updates:
@@ -7,8 +12,7 @@
7
12
  - added missing docs for `config.dead_request_ttl`;
8
13
  - some minor updates;
9
14
  ### Changed
10
- - `#clear_dead_requests`: `:scan_size` is equal to `config[:lock_release_batch_size]` now (instead of to `config[:key_extraction_batch_size]`);
11
- cuz `#clear_dead_requests` works with lock releasing;
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;
12
16
 
13
17
  ## [1.0.0] - 2024-04-01
14
18
  - First Major Release;
@@ -195,7 +199,7 @@
195
199
  ### Changed
196
200
  - The lock acquier identifier (`acq_id`) now includes the fiber id, the ractor id and an unique per-process
197
201
  10 byte string. It is added in order to prevent collisions between different processes/pods
198
- 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
199
203
  to the same position with the same `acq_id` for different processes/pods in the lock request queue.
200
204
 
201
205
  ## [0.0.8] - 2024-02-27
data/README.md CHANGED
@@ -150,8 +150,8 @@ 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)
@@ -324,10 +324,12 @@ def lock(
324
324
  - should be logged the each try of lock acquiring (a lot of logs can be generated depending on your retry configurations);
325
325
  - pre-configured in `config[:log_lock_try]`;
326
326
  - `false` by default;
327
- - `block` - `[Block]`
327
+ - `block` - (optional) `[Block]`
328
328
  - A block of code that should be executed after the successfully acquired lock.
329
329
  - If block is **passed** the obtained lock will be released after the block execution or it's ttl (what will happen first);
330
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) { ... }`)
331
333
 
332
334
  Return value:
333
335
 
@@ -453,6 +455,43 @@ rql.lock_info("my_lock")
453
455
  }
454
456
  ```
455
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
+
456
495
  ---
457
496
 
458
497
  #### #lock! - exceptional lock obtaining
@@ -563,9 +602,9 @@ rql.queue_info("your_lock_name")
563
602
  {
564
603
  "lock_queue" => "rql:lock_queue:your_lock_name",
565
604
  "queue" => [
566
- { "acq_id" => "rql:acq:123/456/567/678/fa76df9cc2", "score" => 1},
567
- { "acq_id" => "rql:acq:123/567/456/679/c7bfcaf4f9", "score" => 2},
568
- { "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},
569
608
  # ...etc
570
609
  ]
571
610
  }
@@ -587,6 +626,8 @@ rql.locked?("your_lock_name") # => true/false
587
626
 
588
627
  #### #queued?
589
628
 
629
+ <sup>\[[back to top](#usage)\]</sup>
630
+
590
631
  - is the lock queued for obtain / has requests for obtain?
591
632
 
592
633
  ```ruby
@@ -635,7 +676,7 @@ rql.unlock("your_lock_name")
635
676
  result: {
636
677
  rel_time: 0.02, # time spent to lock release (in seconds)
637
678
  rel_key: "rql:lock:your_lock_name", # released lock key
638
- 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
639
680
  queue_res: :released, # or :nothing_to_release
640
681
  lock_res: :released # or :nothing_to_release
641
682
  }
@@ -662,12 +703,11 @@ rql.unlock("your_lock_name")
662
703
  - pre-configured value in `config[:isntrumenter]`;
663
704
  - `:instrument` - (optional) `[NilClass,Any]`
664
705
  - custom instrumentation data wich will be passed to the instrumenter's payload with `:instrument` key;
665
-
666
706
  - returns:
667
- - `[Hash<Symbol,Numeric>]` - Format: `{ ok: true, result: Hash<Symbol,Numeric> }`;
668
- - result data:
669
- - `:rel_time` - `Numeric` - time spent to release all locks and related queus;
670
- - `: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);
671
711
 
672
712
  ```ruby
673
713
  rql.clear_locks
@@ -699,13 +739,14 @@ rql.clear_locks
699
739
  - custom logger object;
700
740
  - pre-configured in `config[:logger]`;
701
741
  - returns `{ ok: true, result: :ttl_extended }` when ttl is extended;
702
- - 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
703
743
  some steps of invocation (see **Important** section below);
704
744
  - **Important**:
705
745
  - the method is non-atomic cuz redis does not provide an atomic function for TTL/PTTL extension;
706
746
  - the method consists of two commands:
707
747
  - (1) read current pttl;
708
748
  - (2) set new ttl that is calculated as "current pttl + additional milliseconds";
749
+ - the method uses Redis'es **CAS** (check-and-set) behavior;
709
750
  - what can happen during these steps:
710
751
  - lock is expired between commands or before the first command;
711
752
  - lock is expired before the second command;
@@ -908,7 +949,7 @@ Accepts:
908
949
  - has a preconfigured value in `config[:dead_request_ttl]` (1 day by default);
909
950
  - `:sacn_size` - (optional) `[Integer]`
910
951
  - the batch of scanned keys for Redis'es SCAN command;
911
- - has a preconfigured valie in `config[:key_extraction_batch_size]`;
952
+ - has a preconfigured valie in `config[:lock_release_batch_size]`;
912
953
  - `:logger` - (optional) `[::Logger,#debug]`
913
954
  - custom logger object;
914
955
  - pre-configured in `config[:logger]`;
@@ -994,7 +1035,7 @@ By default `RedisQueuedLocks::Client` is configured with the void notifier (whic
994
1035
 
995
1036
  ### Instrumentation Events
996
1037
 
997
- <sup>\[[back to top](#instrumentation-events)\]</sup>
1038
+ <sup>\[[back to top](#instrumentation)\]</sup>
998
1039
 
999
1040
  List of instrumentation events
1000
1041
 
@@ -1052,6 +1093,7 @@ Detalized event semantics and payload structure:
1052
1093
  <sup>\[[back to top](#table-of-contents)\]</sup>
1053
1094
 
1054
1095
  - **strict redlock algorithm support** (support for many `RedisClient` instances);
1096
+ - deadlock detection (with some options for auto-resolving);
1055
1097
  - Semantic Error objects for unexpected Redis errors;
1056
1098
  - better specs with 100% test coverage (total rework);
1057
1099
  - (non-`timed` locks): per-ruby-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
@@ -1059,6 +1101,7 @@ Detalized event semantics and payload structure:
1059
1101
  whose ttl may expire before the block execution completes). It makes sense for non-`timed` locks *only*;
1060
1102
  - lock request prioritization;
1061
1103
  - support for LIFO strategy;
1104
+ - support for Random Access strategy;
1062
1105
  - more structured logging (separated docs);
1063
1106
  - `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
1064
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,
@@ -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|
@@ -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
6
6
  require_relative 'acquier/acquire_lock'
7
7
  require_relative 'acquier/release_lock'
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  # rubocop:disable Metrics/ClassLength
6
6
  class RedisQueuedLocks::Client
7
- # @since 0.1.0
7
+ # @since 1.0.0
8
8
  include Qonfig::Configurable
9
9
 
10
10
  configuration do
@@ -41,7 +41,7 @@ class RedisQueuedLocks::Client
41
41
  # @return [RedisClient]
42
42
  #
43
43
  # @api private
44
- # @since 0.1.0
44
+ # @since 1.0.0
45
45
  attr_reader :redis_client
46
46
 
47
47
  # NOTE: attr_access here is chosen intentionally in order to have an ability to change
@@ -49,7 +49,7 @@ class RedisQueuedLocks::Client
49
49
  # @return [String]
50
50
  #
51
51
  # @api private
52
- # @since 0.1.0
52
+ # @since 1.0.0
53
53
  attr_accessor :uniq_identity
54
54
 
55
55
  # @param redis_client [RedisClient]
@@ -60,7 +60,7 @@ class RedisQueuedLocks::Client
60
60
  # @return [void]
61
61
  #
62
62
  # @api public
63
- # @since 0.1.0
63
+ # @since 1.0.0
64
64
  def initialize(redis_client, &configs)
65
65
  configure(&configs)
66
66
  @uniq_identity = config[:uniq_identifier].call
@@ -116,7 +116,7 @@ class RedisQueuedLocks::Client
116
116
  # - If block is given the result of block's yeld will be returned.
117
117
  #
118
118
  # @api public
119
- # @since 0.1.0
119
+ # @since 1.0.0
120
120
  def lock(
121
121
  lock_name,
122
122
  ttl: config[:default_lock_ttl],
@@ -164,7 +164,7 @@ class RedisQueuedLocks::Client
164
164
  # @note See #lock method signature.
165
165
  #
166
166
  # @api public
167
- # @since 0.1.0
167
+ # @since 1.0.0
168
168
  def lock!(
169
169
  lock_name,
170
170
  ttl: config[:default_lock_ttl],
@@ -219,7 +219,7 @@ class RedisQueuedLocks::Client
219
219
  # }
220
220
  #
221
221
  # @api public
222
- # @since 0.1.0
222
+ # @since 1.0.0
223
223
  def unlock(
224
224
  lock_name,
225
225
  logger: config[:logger],
@@ -238,7 +238,7 @@ class RedisQueuedLocks::Client
238
238
  # @return [Boolean]
239
239
  #
240
240
  # @api public
241
- # @since 0.1.0
241
+ # @since 1.0.0
242
242
  def locked?(lock_name)
243
243
  RedisQueuedLocks::Acquier::IsLocked.locked?(redis_client, lock_name)
244
244
  end
@@ -247,7 +247,7 @@ class RedisQueuedLocks::Client
247
247
  # @return [Boolean]
248
248
  #
249
249
  # @api public
250
- # @since 0.1.0
250
+ # @since 1.0.0
251
251
  def queued?(lock_name)
252
252
  RedisQueuedLocks::Acquier::IsQueued.queued?(redis_client, lock_name)
253
253
  end
@@ -256,7 +256,7 @@ class RedisQueuedLocks::Client
256
256
  # @return [Hash<String,String|Numeric>,NilClass]
257
257
  #
258
258
  # @api public
259
- # @since 0.1.0
259
+ # @since 1.0.0
260
260
  def lock_info(lock_name)
261
261
  RedisQueuedLocks::Acquier::LockInfo.lock_info(redis_client, lock_name)
262
262
  end
@@ -265,7 +265,7 @@ class RedisQueuedLocks::Client
265
265
  # @return [Hash<String|Array<Hash<String,String|Numeric>>,NilClass]
266
266
  #
267
267
  # @api public
268
- # @since 0.1.0
268
+ # @since 1.0.0
269
269
  def queue_info(lock_name)
270
270
  RedisQueuedLocks::Acquier::QueueInfo.queue_info(redis_client, lock_name)
271
271
  end
@@ -288,7 +288,7 @@ class RedisQueuedLocks::Client
288
288
  # - { ok: false, result: :async_expire_or_no_lock }
289
289
  #
290
290
  # @api public
291
- # @since 0.1.0
291
+ # @since 1.0.0
292
292
  def extend_lock_ttl(lock_name, milliseconds, logger: config[:logger])
293
293
  RedisQueuedLocks::Acquier::ExtendLockTTL.extend_lock_ttl(
294
294
  redis_client,
@@ -311,7 +311,7 @@ class RedisQueuedLocks::Client
311
311
  # Example: { ok: true, result { rel_key_cnt: 100, rel_time: 0.01 } }
312
312
  #
313
313
  # @api public
314
- # @since 0.1.0
314
+ # @since 1.0.0
315
315
  def clear_locks(
316
316
  batch_size: config[:lock_release_batch_size],
317
317
  logger: config[:logger],
@@ -345,7 +345,7 @@ class RedisQueuedLocks::Client
345
345
  # @return [Set<String>,Set<Hash<Symbol,Any>>]
346
346
  #
347
347
  # @api public
348
- # @since 0.1.0
348
+ # @since 1.0.0
349
349
  def locks(scan_size: config[:key_extraction_batch_size], with_info: false)
350
350
  RedisQueuedLocks::Acquier::Locks.locks(redis_client, scan_size:, with_info:)
351
351
  end
@@ -356,7 +356,7 @@ class RedisQueuedLocks::Client
356
356
  # @return [Set<Hash<String,Any>>]
357
357
  #
358
358
  # @api public
359
- # @since 0.1.0
359
+ # @since 1.0.0
360
360
  def locks_info(scan_size: config[:key_extraction_batch_size])
361
361
  locks(scan_size:, with_info: true)
362
362
  end
@@ -376,7 +376,7 @@ class RedisQueuedLocks::Client
376
376
  # @return [Set<String>,String<Hash<Symbol,Any>>]
377
377
  #
378
378
  # @api public
379
- # @since 0.1.0
379
+ # @since 1.0.0
380
380
  def queues(scan_size: config[:key_extraction_batch_size], with_info: false)
381
381
  RedisQueuedLocks::Acquier::Queues.queues(redis_client, scan_size:, with_info:)
382
382
  end
@@ -387,7 +387,7 @@ class RedisQueuedLocks::Client
387
387
  # @return [Set<Hash<Symbol,Any>>]
388
388
  #
389
389
  # @api public
390
- # @since 0.1.0
390
+ # @since 1.0.0
391
391
  def queues_info(scan_size: config[:key_extraction_batch_size])
392
392
  queues(scan_size:, with_info: true)
393
393
  end
@@ -396,7 +396,7 @@ class RedisQueuedLocks::Client
396
396
  # @return [Set<String>]
397
397
  #
398
398
  # @api public
399
- # @since 0.1.0
399
+ # @since 1.0.0
400
400
  def keys(scan_size: config[:key_extraction_batch_size])
401
401
  RedisQueuedLocks::Acquier::Keys.keys(redis_client, scan_size:)
402
402
  end
@@ -415,7 +415,8 @@ class RedisQueuedLocks::Client
415
415
  # Format: { ok: true, result: { processed_queus: Set<String> } }
416
416
  #
417
417
  # @api public
418
- # @since 0.1.0
418
+ # @since 1.0.0
419
+ # @version 1.1.0
419
420
  def clear_dead_requests(
420
421
  dead_ttl: config[:dead_request_ttl],
421
422
  scan_size: config[:lock_release_batch_size],
@@ -1,13 +1,13 @@
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::Debugger::Interface
6
6
  # @param message [String]
7
7
  # @return [void]
8
8
  #
9
9
  # @api private
10
- # @since 0.1.0
10
+ # @since 1.0.0
11
11
  def debug(message)
12
12
  RedisQueuedLocks::Debugger.debug(message)
13
13
  end
@@ -15,7 +15,7 @@ module RedisQueuedLocks::Debugger::Interface
15
15
  # @return [void]
16
16
  #
17
17
  # @api private
18
- # @since 0.1.0
18
+ # @since 1.0.0
19
19
  def enable_debugger!
20
20
  RedisQueuedLocks::Debugger.enable!
21
21
  end
@@ -23,7 +23,7 @@ module RedisQueuedLocks::Debugger::Interface
23
23
  # @return [void]
24
24
  #
25
25
  # @api private
26
- # @since 0.1.0
26
+ # @since 1.0.0
27
27
  def disable_debugger!
28
28
  RedisQueuedLocks::Debugger.disable!
29
29
  end
@@ -1,14 +1,14 @@
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::Debugger
6
6
  require_relative 'debugger/interface'
7
7
 
8
8
  # @return [String]
9
9
  #
10
10
  # @api private
11
- # @since 0.1.0
11
+ # @since 1.0.0
12
12
  DEBUG_ENABLED_METHOD = <<~METHOD_DECLARATION.strip.freeze
13
13
  def debug(message) = STDOUT.write("#\{message}\n")
14
14
  METHOD_DECLARATION
@@ -16,20 +16,20 @@ module RedisQueuedLocks::Debugger
16
16
  # @return [String]
17
17
  #
18
18
  # @api private
19
- # @since 0.1.0
19
+ # @since 1.0.0
20
20
  DEBUG_DISABLED_MEHTOD = <<~METHOD_DECLARATION.strip.freeze
21
21
  def debug(message); end
22
22
  METHOD_DECLARATION
23
23
 
24
24
  class << self
25
25
  # @api private
26
- # @since 0.1.0
26
+ # @since 1.0.0
27
27
  instance_variable_set(:@enabled, false)
28
28
 
29
29
  # @return [void]
30
30
  #
31
31
  # @api private
32
- # @since 0.1.0
32
+ # @since 1.0.0
33
33
  def enable!
34
34
  @enabled = true
35
35
  eval(DEBUG_ENABLED_METHOD)
@@ -38,7 +38,7 @@ module RedisQueuedLocks::Debugger
38
38
  # @return [void]
39
39
  #
40
40
  # @api private
41
- # @since 0.1.0
41
+ # @since 1.0.0
42
42
  def disable!
43
43
  @enabled = false
44
44
  eval(DEBUG_DISABLED_MEHTOD)
@@ -47,7 +47,7 @@ module RedisQueuedLocks::Debugger
47
47
  # @return [Boolean]
48
48
  #
49
49
  # @api private
50
- # @since 0.1.0
50
+ # @since 1.0.0
51
51
  def enabled?
52
52
  @enabled
53
53
  end
@@ -56,7 +56,7 @@ module RedisQueuedLocks::Debugger
56
56
  # @return [void]
57
57
  #
58
58
  # @api private
59
- # @since 0.1.0
59
+ # @since 1.0.0
60
60
  def debug(message); end
61
61
  end
62
62
  end
@@ -2,26 +2,26 @@
2
2
 
3
3
  module RedisQueuedLocks
4
4
  # @api public
5
- # @since 0.1.0
5
+ # @since 1.0.0
6
6
  Error = Class.new(::StandardError)
7
7
 
8
8
  # @api public
9
- # @since 0.1.0
9
+ # @since 1.0.0
10
10
  ArgumentError = Class.new(::ArgumentError)
11
11
 
12
12
  # @api public
13
- # @since 0.1.0
13
+ # @since 1.0.0
14
14
  LockAlreadyObtainedError = Class.new(Error)
15
15
 
16
16
  # @api public
17
- # @since 0.1.0
17
+ # @since 1.0.0
18
18
  LockAcquiermentTimeoutError = Class.new(Error)
19
19
 
20
20
  # @api public
21
- # @since 0.1.0
21
+ # @since 1.0.0
22
22
  LockAcquiermentRetryLimitError = Class.new(Error)
23
23
 
24
24
  # @api pulic
25
- # @since 0.1.0
25
+ # @since 1.0.0
26
26
  TimedLockTimeoutError = Class.new(Error)
27
27
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Instrument::ActiveSupport
6
6
  class << self
7
7
  # @param event [String]
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Instrument::ActiveSupport
9
9
  # @return [void]
10
10
  #
11
11
  # @api public
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def notify(event, payload = {})
14
14
  ::ActiveSupport::Notifications.instrument(event, payload)
15
15
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Instrument::VoidNotifier
6
6
  class << self
7
7
  # @param event [String]
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Instrument::VoidNotifier
9
9
  # @return [void]
10
10
  #
11
11
  # @api public
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def notify(event, payload = {}); end
14
14
  end
15
15
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Instrument
6
6
  require_relative 'instrument/void_notifier'
7
7
  require_relative 'instrument/active_support'
@@ -11,7 +11,7 @@ module RedisQueuedLocks::Instrument
11
11
  # @return [Boolean]
12
12
  #
13
13
  # @api public
14
- # @since 0.1.0
14
+ # @since 1.0.0
15
15
  def valid_interface?(instrumenter)
16
16
  if instrumenter == RedisQueuedLocks::Instrument::ActiveSupport
17
17
  # NOTE: active_support should be required in your app
@@ -1,43 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Logging::VoidLogger
6
6
  class << self
7
7
  # @api public
8
- # @since 0.1.0
8
+ # @since 1.0.0
9
9
  def warn(progname = nil, &block); end
10
10
 
11
11
  # @api public
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def unknown(progname = nil, &block); end
14
14
 
15
15
  # @api public
16
- # @since 0.1.0
16
+ # @since 1.0.0
17
17
  def log(progname = nil, &block); end
18
18
 
19
19
  # @api public
20
- # @since 0.1.0
20
+ # @since 1.0.0
21
21
  def info(progname = nil, &block); end
22
22
 
23
23
  # @api public
24
- # @since 0.1.0
24
+ # @since 1.0.0
25
25
  def error(progname = nil, &block); end
26
26
 
27
27
  # @api public
28
- # @since 0.1.0
28
+ # @since 1.0.0
29
29
  def fatal(progname = nil, &block); end
30
30
 
31
31
  # @api public
32
- # @since 0.1.0
32
+ # @since 1.0.0
33
33
  def debug(progname = nil, &block); end
34
34
 
35
35
  # @api public
36
- # @since 0.1.0
36
+ # @since 1.0.0
37
37
  def add(*, &block); end
38
38
 
39
39
  # @api public
40
- # @since 0.1.0
40
+ # @since 1.0.0
41
41
  def <<(message); end
42
42
  end
43
43
  end
@@ -1,19 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 1.0.0
5
5
  module RedisQueuedLocks::Logging
6
6
  require_relative 'logging/void_logger'
7
7
 
8
8
  class << self
9
- # @param logger [::Logger,#debug]
9
+ # @param logger [::Logger,#debug,::SemanticLogger::Logger]
10
10
  # @return [Boolean]
11
11
  #
12
12
  # @api public
13
- # @since 0.1.0
13
+ # @since 1.0.0
14
+ # @version 1.2.0
14
15
  def valid_interface?(logger)
15
16
  return true if logger.is_a?(::Logger)
16
17
 
18
+ # NOTE:
19
+ # - convinient/conventional way to support the popular`semantic_logger` library
20
+ # - see https://logger.rocketjob.io/
21
+ # - see https://github.com/reidmorrison/semantic_logger
22
+ return true if defined?(::SemanticLogger::Logger) && logger.is_a?(::SemanticLogger::Logger)
23
+
17
24
  # NOTE: should provide `#debug` method.
18
25
  return false unless logger.respond_to?(:debug)
19
26
 
@@ -1,24 +1,24 @@
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::Resource
6
6
  # @return [String]
7
7
  #
8
8
  # @api private
9
- # @since 0.1.0
9
+ # @since 1.0.0
10
10
  KEY_PATTERN = 'rql:lock*'
11
11
 
12
12
  # @return [String]
13
13
  #
14
14
  # @api private
15
- # @since 0.1.0
15
+ # @since 1.0.0
16
16
  LOCK_PATTERN = 'rql:lock:*'
17
17
 
18
18
  # @return [String]
19
19
  #
20
20
  # @api private
21
- # @since 0.1.0
21
+ # @since 1.0.0
22
22
  LOCK_QUEUE_PATTERN = 'rql:lock_queue:*'
23
23
 
24
24
  class << self
@@ -29,7 +29,7 @@ module RedisQueuedLocks::Resource
29
29
  # @return [String]
30
30
  #
31
31
  # @api private
32
- # @since 0.1.0
32
+ # @since 1.0.0
33
33
  def calc_uniq_identity
34
34
  SecureRandom.hex(8)
35
35
  end
@@ -42,7 +42,7 @@ module RedisQueuedLocks::Resource
42
42
  # @return [String]
43
43
  #
44
44
  # @api private
45
- # @since 0.1.0
45
+ # @since 1.0.0
46
46
  def acquier_identifier(process_id, thread_id, fiber_id, ractor_id, identity)
47
47
  "rql:acq:#{process_id}/#{thread_id}/#{fiber_id}/#{ractor_id}/#{identity}"
48
48
  end
@@ -51,7 +51,7 @@ module RedisQueuedLocks::Resource
51
51
  # @return [String]
52
52
  #
53
53
  # @api private
54
- # @since 0.1.0
54
+ # @since 1.0.0
55
55
  def prepare_lock_key(lock_name)
56
56
  "rql:lock:#{lock_name}"
57
57
  end
@@ -60,7 +60,7 @@ module RedisQueuedLocks::Resource
60
60
  # @return [String]
61
61
  #
62
62
  # @api private
63
- # @since 0.1.0
63
+ # @since 1.0.0
64
64
  def prepare_lock_queue(lock_name)
65
65
  "rql:lock_queue:#{lock_name}"
66
66
  end
@@ -68,7 +68,7 @@ module RedisQueuedLocks::Resource
68
68
  # @return [Float] Redis's <Set> score that is calculated from the time (epoch) as a float.
69
69
  #
70
70
  # @api private
71
- # @since 0.1.0
71
+ # @since 1.0.0
72
72
  def calc_initial_acquier_position
73
73
  Time.now.to_f
74
74
  end
@@ -77,7 +77,7 @@ module RedisQueuedLocks::Resource
77
77
  # @return [Float] Redis's <Set> score barrier for acquiers that should be removed from queue.
78
78
  #
79
79
  # @api private
80
- # @since 0.1.0
80
+ # @since 1.0.0
81
81
  def acquier_dead_score(queue_ttl)
82
82
  Time.now.to_f - queue_ttl
83
83
  end
@@ -91,7 +91,7 @@ module RedisQueuedLocks::Resource
91
91
  # Is the lock request time limit has reached or not.
92
92
  #
93
93
  # @api private
94
- # @since 0.1.0
94
+ # @since 1.0.0
95
95
  def dead_score_reached?(acquier_position, queue_ttl)
96
96
  (acquier_position + queue_ttl) < Time.now.to_f
97
97
  end
@@ -100,7 +100,7 @@ module RedisQueuedLocks::Resource
100
100
  # @return [String]
101
101
  #
102
102
  # @api private
103
- # @since 0.1.0
103
+ # @since 1.0.0
104
104
  def lock_key_from_queue(lock_queue)
105
105
  # NOTE: 15 is a start position of the lock name
106
106
  "rql:lock:#{lock_queue[15..]}"
@@ -109,7 +109,7 @@ module RedisQueuedLocks::Resource
109
109
  # @return [Integer]
110
110
  #
111
111
  # @api private
112
- # @since 0.1.0
112
+ # @since 1.0.0
113
113
  def get_thread_id
114
114
  ::Thread.current.object_id
115
115
  end
@@ -117,7 +117,7 @@ module RedisQueuedLocks::Resource
117
117
  # @return [Integer]
118
118
  #
119
119
  # @api private
120
- # @since 0.1.0
120
+ # @since 1.0.0
121
121
  def get_fiber_id
122
122
  ::Fiber.current.object_id
123
123
  end
@@ -125,7 +125,7 @@ module RedisQueuedLocks::Resource
125
125
  # @return [Integer]
126
126
  #
127
127
  # @api private
128
- # @since 0.1.0
128
+ # @since 1.0.0
129
129
  def get_ractor_id
130
130
  ::Ractor.current.object_id
131
131
  end
@@ -133,7 +133,7 @@ module RedisQueuedLocks::Resource
133
133
  # @return [Integer]
134
134
  #
135
135
  # @api private
136
- # @since 0.1.0
136
+ # @since 1.0.0
137
137
  def get_process_id
138
138
  ::Process.pid
139
139
  end
@@ -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::Utilities
6
6
  module_function
7
7
 
@@ -9,7 +9,7 @@ module RedisQueuedLocks::Utilities
9
9
  # @return [Any]
10
10
  #
11
11
  # @api private
12
- # @since 0.1.0
12
+ # @since 1.0.0
13
13
  def run_non_critical(&block)
14
14
  yield rescue nil
15
15
  end
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 1.1.0
9
- VERSION = '1.1.0'
8
+ # @version 1.2.0
9
+ VERSION = '1.2.0'
10
10
  end
@@ -7,7 +7,7 @@ require 'securerandom'
7
7
  require 'logger'
8
8
 
9
9
  # @api public
10
- # @since 0.1.0
10
+ # @since 1.0.0
11
11
  module RedisQueuedLocks
12
12
  require_relative 'redis_queued_locks/version'
13
13
  require_relative 'redis_queued_locks/errors'
@@ -20,6 +20,6 @@ module RedisQueuedLocks
20
20
  require_relative 'redis_queued_locks/instrument'
21
21
  require_relative 'redis_queued_locks/client'
22
22
 
23
- # @since 0.1.0
23
+ # @since 1.0.0
24
24
  extend RedisQueuedLocks::Debugger::Interface
25
25
  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.1.0
4
+ version: 1.2.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-04-02 00:00:00.000000000 Z
11
+ date: 2024-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client