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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -3
- data/README.md +58 -15
- data/lib/redis_queued_locks/acquier/acquire_lock/delay_execution.rb +2 -2
- data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb +4 -4
- data/lib/redis_queued_locks/acquier/acquire_lock/with_acq_timeout.rb +2 -2
- data/lib/redis_queued_locks/acquier/acquire_lock/yield_with_expire.rb +4 -4
- data/lib/redis_queued_locks/acquier/acquire_lock.rb +8 -8
- data/lib/redis_queued_locks/acquier/clear_dead_requests.rb +3 -3
- data/lib/redis_queued_locks/acquier/extend_lock_ttl.rb +3 -3
- data/lib/redis_queued_locks/acquier/is_locked.rb +2 -2
- data/lib/redis_queued_locks/acquier/is_queued.rb +2 -2
- data/lib/redis_queued_locks/acquier/keys.rb +2 -2
- data/lib/redis_queued_locks/acquier/lock_info.rb +2 -2
- data/lib/redis_queued_locks/acquier/locks.rb +4 -4
- data/lib/redis_queued_locks/acquier/queue_info.rb +2 -2
- data/lib/redis_queued_locks/acquier/queues.rb +4 -4
- data/lib/redis_queued_locks/acquier/release_all_locks.rb +4 -4
- data/lib/redis_queued_locks/acquier/release_lock.rb +4 -4
- data/lib/redis_queued_locks/acquier.rb +1 -1
- data/lib/redis_queued_locks/client.rb +21 -20
- data/lib/redis_queued_locks/debugger/interface.rb +4 -4
- data/lib/redis_queued_locks/debugger.rb +8 -8
- data/lib/redis_queued_locks/errors.rb +6 -6
- data/lib/redis_queued_locks/instrument/active_support.rb +2 -2
- data/lib/redis_queued_locks/instrument/void_notifier.rb +2 -2
- data/lib/redis_queued_locks/instrument.rb +2 -2
- data/lib/redis_queued_locks/logging/void_logger.rb +10 -10
- data/lib/redis_queued_locks/logging.rb +10 -3
- data/lib/redis_queued_locks/resource.rb +16 -16
- data/lib/redis_queued_locks/utilities.rb +2 -2
- data/lib/redis_queued_locks/version.rb +2 -2
- data/lib/redis_queued_locks.rb +2 -2
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6b1c8d60f41d2dc4f3eda798efa02a4764b877e6666e8babd7cf1a7827a4b288
         | 
| 4 | 
            +
              data.tar.gz: 983e142251b344055013aa2aac2965ad542d44f5c8f81ac410f97cdef7b216b3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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  | 
| 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  | 
| 154 | 
            -
              # - affects the  | 
| 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" =>  | 
| 567 | 
            -
                { "acq_id" => "rql:acq:123/567/456/679/c7bfcaf4f9", "score" =>  | 
| 568 | 
            -
                { "acq_id" => "rql:acq:555/329/523/127/7329553b11", "score" =>  | 
| 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 | 
            -
             | 
| 668 | 
            -
             | 
| 669 | 
            -
             | 
| 670 | 
            -
             | 
| 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[: | 
| 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 | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            # rubocop:disable Metrics/ModuleLength, Metrics/BlockNesting
         | 
| 6 6 | 
             
            module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
         | 
| 7 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
         | 
| 6 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 15 | 
            +
              # @since 1.0.0
         | 
| 16 16 | 
             
              extend TryToLock
         | 
| 17 | 
            -
              # @since  | 
| 17 | 
            +
              # @since 1.0.0
         | 
| 18 18 | 
             
              extend DelayExecution
         | 
| 19 | 
            -
              # @since  | 
| 19 | 
            +
              # @since 1.0.0
         | 
| 20 20 | 
             
              extend YieldWithExpire
         | 
| 21 | 
            -
              # @since  | 
| 21 | 
            +
              # @since 1.0.0
         | 
| 22 22 | 
             
              extend WithAcqTimeout
         | 
| 23 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Acquier::ExtendLockTTL
         | 
| 6 6 | 
             
              # @return [String]
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # @api private
         | 
| 9 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Acquier::ReleaseAllLocks
         | 
| 6 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Acquier::ReleaseLock
         | 
| 6 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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,10 +1,10 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            # @api public
         | 
| 4 | 
            -
            # @since  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            # rubocop:disable Metrics/ClassLength
         | 
| 6 6 | 
             
            class RedisQueuedLocks::Client
         | 
| 7 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 5 | 
            +
              # @since 1.0.0
         | 
| 6 6 | 
             
              Error = Class.new(::StandardError)
         | 
| 7 7 |  | 
| 8 8 | 
             
              # @api public
         | 
| 9 | 
            -
              # @since  | 
| 9 | 
            +
              # @since 1.0.0
         | 
| 10 10 | 
             
              ArgumentError = Class.new(::ArgumentError)
         | 
| 11 11 |  | 
| 12 12 | 
             
              # @api public
         | 
| 13 | 
            -
              # @since  | 
| 13 | 
            +
              # @since 1.0.0
         | 
| 14 14 | 
             
              LockAlreadyObtainedError = Class.new(Error)
         | 
| 15 15 |  | 
| 16 16 | 
             
              # @api public
         | 
| 17 | 
            -
              # @since  | 
| 17 | 
            +
              # @since 1.0.0
         | 
| 18 18 | 
             
              LockAcquiermentTimeoutError = Class.new(Error)
         | 
| 19 19 |  | 
| 20 20 | 
             
              # @api public
         | 
| 21 | 
            -
              # @since  | 
| 21 | 
            +
              # @since 1.0.0
         | 
| 22 22 | 
             
              LockAcquiermentRetryLimitError = Class.new(Error)
         | 
| 23 23 |  | 
| 24 24 | 
             
              # @api pulic
         | 
| 25 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Logging::VoidLogger
         | 
| 6 6 | 
             
              class << self
         | 
| 7 7 | 
             
                # @api public
         | 
| 8 | 
            -
                # @since  | 
| 8 | 
            +
                # @since 1.0.0
         | 
| 9 9 | 
             
                def warn(progname = nil, &block); end
         | 
| 10 10 |  | 
| 11 11 | 
             
                # @api public
         | 
| 12 | 
            -
                # @since  | 
| 12 | 
            +
                # @since 1.0.0
         | 
| 13 13 | 
             
                def unknown(progname = nil, &block); end
         | 
| 14 14 |  | 
| 15 15 | 
             
                # @api public
         | 
| 16 | 
            -
                # @since  | 
| 16 | 
            +
                # @since 1.0.0
         | 
| 17 17 | 
             
                def log(progname = nil, &block); end
         | 
| 18 18 |  | 
| 19 19 | 
             
                # @api public
         | 
| 20 | 
            -
                # @since  | 
| 20 | 
            +
                # @since 1.0.0
         | 
| 21 21 | 
             
                def info(progname = nil, &block); end
         | 
| 22 22 |  | 
| 23 23 | 
             
                # @api public
         | 
| 24 | 
            -
                # @since  | 
| 24 | 
            +
                # @since 1.0.0
         | 
| 25 25 | 
             
                def error(progname = nil, &block); end
         | 
| 26 26 |  | 
| 27 27 | 
             
                # @api public
         | 
| 28 | 
            -
                # @since  | 
| 28 | 
            +
                # @since 1.0.0
         | 
| 29 29 | 
             
                def fatal(progname = nil, &block); end
         | 
| 30 30 |  | 
| 31 31 | 
             
                # @api public
         | 
| 32 | 
            -
                # @since  | 
| 32 | 
            +
                # @since 1.0.0
         | 
| 33 33 | 
             
                def debug(progname = nil, &block); end
         | 
| 34 34 |  | 
| 35 35 | 
             
                # @api public
         | 
| 36 | 
            -
                # @since  | 
| 36 | 
            +
                # @since 1.0.0
         | 
| 37 37 | 
             
                def add(*, &block); end
         | 
| 38 38 |  | 
| 39 39 | 
             
                # @api public
         | 
| 40 | 
            -
                # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 4 | 
            +
            # @since 1.0.0
         | 
| 5 5 | 
             
            module RedisQueuedLocks::Resource
         | 
| 6 6 | 
             
              # @return [String]
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # @api private
         | 
| 9 | 
            -
              # @since  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 12 | 
            +
              # @since 1.0.0
         | 
| 13 13 | 
             
              def run_non_critical(&block)
         | 
| 14 14 | 
             
                yield rescue nil
         | 
| 15 15 | 
             
              end
         | 
    
        data/lib/redis_queued_locks.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ require 'securerandom' | |
| 7 7 | 
             
            require 'logger'
         | 
| 8 8 |  | 
| 9 9 | 
             
            # @api public
         | 
| 10 | 
            -
            # @since  | 
| 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  | 
| 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. | 
| 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- | 
| 11 | 
            +
            date: 2024-04-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: redis-client
         |