redis_queued_locks 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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