redis_queued_locks 1.12.1 → 1.14.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/.rubocop.yml +3 -1
 - data/.ruby-version +1 -1
 - data/CHANGELOG.md +45 -5
 - data/LICENSE.txt +1 -1
 - data/README.md +574 -296
 - data/Rakefile +12 -4
 - data/Steepfile +15 -0
 - data/github_ci/ruby3.3.gemfile +17 -0
 - data/github_ci/ruby3.3.gemfile.lock +217 -0
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/delay_execution.rb +4 -4
 - data/lib/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +40 -0
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/dequeue_from_lock_queue.rb +17 -8
 - data/lib/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rb +166 -0
 - data/lib/redis_queued_locks/acquirer/acquire_lock/log_visitor.rb +218 -0
 - data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rb +543 -0
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/try_to_lock.rb +126 -92
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/with_acq_timeout.rb +14 -9
 - data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire/log_visitor.rb +76 -0
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/yield_expire.rb +42 -19
 - data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock.rb +74 -47
 - data/lib/redis_queued_locks/{acquier → acquirer}/clear_dead_requests.rb +5 -3
 - data/lib/redis_queued_locks/{acquier → acquirer}/extend_lock_ttl.rb +4 -3
 - data/lib/redis_queued_locks/{acquier → acquirer}/is_locked.rb +1 -1
 - data/lib/redis_queued_locks/{acquier → acquirer}/is_queued.rb +1 -1
 - data/lib/redis_queued_locks/{acquier → acquirer}/keys.rb +5 -5
 - data/lib/redis_queued_locks/{acquier → acquirer}/lock_info.rb +9 -5
 - data/lib/redis_queued_locks/{acquier → acquirer}/locks.rb +16 -3
 - data/lib/redis_queued_locks/{acquier → acquirer}/queue_info.rb +8 -6
 - data/lib/redis_queued_locks/{acquier → acquirer}/queues.rb +9 -2
 - data/lib/redis_queued_locks/{acquier → acquirer}/release_all_locks.rb +26 -21
 - data/lib/redis_queued_locks/{acquier → acquirer}/release_lock.rb +28 -22
 - data/lib/redis_queued_locks/acquirer/release_locks_of.rb +211 -0
 - data/lib/redis_queued_locks/acquirer.rb +19 -0
 - data/lib/redis_queued_locks/client.rb +317 -254
 - data/lib/redis_queued_locks/config/dsl.rb +94 -0
 - data/lib/redis_queued_locks/config.rb +236 -0
 - data/lib/redis_queued_locks/data.rb +2 -0
 - data/lib/redis_queued_locks/errors.rb +27 -11
 - data/lib/redis_queued_locks/instrument.rb +11 -4
 - data/lib/redis_queued_locks/logging/void_logger.rb +38 -1
 - data/lib/redis_queued_locks/logging.rb +20 -5
 - data/lib/redis_queued_locks/resource.rb +49 -11
 - data/lib/redis_queued_locks/swarm/acquirers.rb +17 -16
 - data/lib/redis_queued_locks/swarm/flush_zombies.rb +26 -25
 - data/lib/redis_queued_locks/swarm/probe_hosts.rb +20 -19
 - data/lib/redis_queued_locks/swarm/redis_client_builder.rb +3 -3
 - data/lib/redis_queued_locks/swarm/supervisor.rb +19 -6
 - data/lib/redis_queued_locks/swarm/swarm_element/isolated.rb +20 -18
 - data/lib/redis_queued_locks/swarm/swarm_element/threaded.rb +35 -27
 - data/lib/redis_queued_locks/swarm/zombie_info.rb +9 -9
 - data/lib/redis_queued_locks/swarm.rb +20 -41
 - data/lib/redis_queued_locks/utilities.rb +11 -2
 - data/lib/redis_queued_locks/version.rb +2 -2
 - data/lib/redis_queued_locks.rb +2 -3
 - data/rbs_collection.lock.yaml +28 -0
 - data/rbs_collection.yaml +17 -0
 - data/redis_queued_locks.gemspec +22 -23
 - data/sig/manifest.yml +6 -0
 - data/sig/redis_queued_locks/acquier.rbs +4 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/delay_execution.rbs +9 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rbs +21 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue.rbs +26 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rbs +71 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/log_visitor.rbs +72 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rbs +179 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rbs +48 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/with_acq_timeout.rbs +19 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/yield_expire.rbs +41 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock/yield_with_expire/log_visitor.rbs +32 -0
 - data/sig/redis_queued_locks/acquirer/acquire_lock.rbs +52 -0
 - data/sig/redis_queued_locks/acquirer/clear_dead_requests.rbs +28 -0
 - data/sig/redis_queued_locks/acquirer/extend_lock_ttl.rbs +28 -0
 - data/sig/redis_queued_locks/acquirer/is_locked.rbs +9 -0
 - data/sig/redis_queued_locks/acquirer/is_queued.rbs +9 -0
 - data/sig/redis_queued_locks/acquirer/keys.rbs +10 -0
 - data/sig/redis_queued_locks/acquirer/lock_info.rbs +10 -0
 - data/sig/redis_queued_locks/acquirer/locks.rbs +16 -0
 - data/sig/redis_queued_locks/acquirer/queue_info.rbs +13 -0
 - data/sig/redis_queued_locks/acquirer/queues.rbs +16 -0
 - data/sig/redis_queued_locks/acquirer/release_all_locks.rbs +30 -0
 - data/sig/redis_queued_locks/acquirer/release_lock.rbs +38 -0
 - data/sig/redis_queued_locks/acquirer/release_locks_of.rbs +46 -0
 - data/sig/redis_queued_locks/client.rbs +235 -0
 - data/sig/redis_queued_locks/config/dsl.rbs +26 -0
 - data/sig/redis_queued_locks/config.rbs +23 -0
 - data/sig/redis_queued_locks/data.rbs +4 -0
 - data/sig/redis_queued_locks/debugger/interface.rbs +9 -0
 - data/sig/redis_queued_locks/debugger.rbs +13 -0
 - data/sig/redis_queued_locks/errors.rbs +43 -0
 - data/sig/redis_queued_locks/instrument/active_support.rbs +7 -0
 - data/sig/redis_queued_locks/instrument/sampler.rbs +9 -0
 - data/sig/redis_queued_locks/instrument/void_notifier.rbs +7 -0
 - data/sig/redis_queued_locks/instrument.rbs +15 -0
 - data/sig/redis_queued_locks/logging/sampler.rbs +9 -0
 - data/sig/redis_queued_locks/logging/void_logger.rbs +15 -0
 - data/sig/redis_queued_locks/logging.rbs +15 -0
 - data/sig/redis_queued_locks/resource.rbs +42 -0
 - data/sig/redis_queued_locks/swarm/acquirers.rbs +10 -0
 - data/sig/redis_queued_locks/swarm/flush_zombies.rbs +13 -0
 - data/sig/redis_queued_locks/swarm/probe_hosts.rbs +13 -0
 - data/sig/redis_queued_locks/swarm/redis_client_builder.rbs +19 -0
 - data/sig/redis_queued_locks/swarm/supervisor.rbs +26 -0
 - data/sig/redis_queued_locks/swarm/swarm_element/isolated.rbs +52 -0
 - data/sig/redis_queued_locks/swarm/swarm_element/threaded.rbs +61 -0
 - data/sig/redis_queued_locks/swarm/swarm_element.rbs +8 -0
 - data/sig/redis_queued_locks/swarm/zombie_info.rbs +24 -0
 - data/sig/redis_queued_locks/swarm.rbs +41 -0
 - data/sig/redis_queued_locks/utilities/lock.rbs +10 -0
 - data/sig/redis_queued_locks/utilities.rbs +12 -0
 - data/sig/redis_queued_locks/version.rbs +3 -0
 - data/sig/redis_queued_locks.rbs +14 -0
 - data/sig/vendor/active_support.rbs +9 -0
 - data/sig/vendor/redis_client.rbs +39 -0
 - data/sig/vendor/semantic_logger.rbs +4 -0
 - metadata +98 -54
 - data/lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +0 -40
 - data/lib/redis_queued_locks/acquier/acquire_lock/instr_visitor.rb +0 -166
 - data/lib/redis_queued_locks/acquier/acquire_lock/log_visitor.rb +0 -216
 - data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock/log_visitor.rb +0 -541
 - data/lib/redis_queued_locks/acquier/acquire_lock/yield_expire/log_visitor.rb +0 -76
 - data/lib/redis_queued_locks/acquier.rb +0 -18
 
| 
         @@ -3,7 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # @api private
         
     | 
| 
       4 
4 
     | 
    
         
             
            # @since 1.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            # @version 1.7.0
         
     | 
| 
       6 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 6 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::AcquireLock::YieldExpire
         
     | 
| 
       7 
7 
     | 
    
         
             
              require_relative 'yield_expire/log_visitor'
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
              # @return [String]
         
     | 
| 
         @@ -18,14 +18,13 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       18 
18 
     | 
    
         
             
              # @param redis [RedisClient] Redis connection.
         
     | 
| 
       19 
19 
     | 
    
         
             
              # @param logger [::Logger,#debug] Logger object.
         
     | 
| 
       20 
20 
     | 
    
         
             
              # @param lock_key [String] Obtained lock key that should be expired.
         
     | 
| 
       21 
     | 
    
         
            -
              # @param  
     | 
| 
      
 21 
     | 
    
         
            +
              # @param acquirer_id [String] Acquirer identifier.
         
     | 
| 
       22 
22 
     | 
    
         
             
              # @param host_id [String] Host identifier.
         
     | 
| 
       23 
23 
     | 
    
         
             
              # @param access_strategy [Symbol] Lock obtaining strategy.
         
     | 
| 
       24 
24 
     | 
    
         
             
              # @param timed [Boolean] Should the lock be wrapped by Timeout with with lock's ttl
         
     | 
| 
       25 
     | 
    
         
            -
              # @param ttl_shift [ 
     | 
| 
      
 25 
     | 
    
         
            +
              # @param ttl_shift [Numeric] Lock's TTL shifting. Should affect block's ttl. In millisecodns.
         
     | 
| 
       26 
26 
     | 
    
         
             
              # @param ttl [Integer,NilClass] Lock's time to live (in ms). Nil means "without timeout".
         
     | 
| 
       27 
27 
     | 
    
         
             
              # @param queue_ttl [Integer] Lock request lifetime.
         
     | 
| 
       28 
     | 
    
         
            -
              # @param block [Block] Custom logic that should be invoked unter the obtained lock.
         
     | 
| 
       29 
28 
     | 
    
         
             
              # @param meta [NilClass,Hash<String|Symbol,Any>] Custom metadata wich is passed to the lock data;
         
     | 
| 
       30 
29 
     | 
    
         
             
              # @param log_sampled [Boolean] Should the logic be logged or not.
         
     | 
| 
       31 
30 
     | 
    
         
             
              # @param instr_sampled [Boolean] Should the logic be instrumented or not.
         
     | 
| 
         @@ -33,7 +32,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       33 
32 
     | 
    
         
             
              # @param should_decrease [Boolean]
         
     | 
| 
       34 
33 
     | 
    
         
             
              #   - Should decrease the lock TTL after the lock invocation;
         
     | 
| 
       35 
34 
     | 
    
         
             
              #   - It is suitable for extendable reentrant locks;
         
     | 
| 
       36 
     | 
    
         
            -
              # @ 
     | 
| 
      
 35 
     | 
    
         
            +
              # @param block [Block] Custom logic that should be invoked under the obtained lock.
         
     | 
| 
      
 36 
     | 
    
         
            +
              # @return [Any,NilClass] nil is returned when no block parametr is provided.
         
     | 
| 
       37 
37 
     | 
    
         
             
              #
         
     | 
| 
       38 
38 
     | 
    
         
             
              # @api private
         
     | 
| 
       39 
39 
     | 
    
         
             
              # @since 1.3.0
         
     | 
| 
         @@ -43,7 +43,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       43 
43 
     | 
    
         
             
                redis,
         
     | 
| 
       44 
44 
     | 
    
         
             
                logger,
         
     | 
| 
       45 
45 
     | 
    
         
             
                lock_key,
         
     | 
| 
       46 
     | 
    
         
            -
                 
     | 
| 
      
 46 
     | 
    
         
            +
                acquirer_id,
         
     | 
| 
       47 
47 
     | 
    
         
             
                host_id,
         
     | 
| 
       48 
48 
     | 
    
         
             
                access_strategy,
         
     | 
| 
       49 
49 
     | 
    
         
             
                timed,
         
     | 
| 
         @@ -60,33 +60,56 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       60 
60 
     | 
    
         
             
                initial_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         
             
                if block_given?
         
     | 
| 
       63 
     | 
    
         
            -
                  timeout = ((ttl - ttl_shift) / 1_000.0).yield_self do |time|
         
     | 
| 
       64 
     | 
    
         
            -
                    # NOTE: time in <seconds> cuz Ruby's Timeout requires <seconds>
         
     | 
| 
       65 
     | 
    
         
            -
                    (time < 0) ? 0.0 : time
         
     | 
| 
       66 
     | 
    
         
            -
                  end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
63 
     | 
    
         
             
                  if timed && ttl != nil
         
     | 
| 
       69 
     | 
    
         
            -
                     
     | 
| 
      
 64 
     | 
    
         
            +
                    # NOTE:
         
     | 
| 
      
 65 
     | 
    
         
            +
                    #   - steep is ignored cuz steep can not recognize `::Integer - ::Integer|::Float`
         
     | 
| 
      
 66 
     | 
    
         
            +
                    #     operation here for some mystical reason (it tryes to find overloadd `-` method for
         
     | 
| 
      
 67 
     | 
    
         
            +
                    #     integer and fails on it);
         
     | 
| 
      
 68 
     | 
    
         
            +
                    #   - so we need to ignore steep here at all and manually set the type of each
         
     | 
| 
      
 69 
     | 
    
         
            +
                    #     variable for the correct following variable type recognitions;
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    # steep:ignore:start
         
     | 
| 
      
 72 
     | 
    
         
            +
                    # @type var ttl: Integer
         
     | 
| 
      
 73 
     | 
    
         
            +
                    # @type var ttl_shift: Float|Integer
         
     | 
| 
      
 74 
     | 
    
         
            +
                    # @type var timeout: Float
         
     | 
| 
      
 75 
     | 
    
         
            +
                    timeout = ((ttl - ttl_shift) / 1_000.0).yield_self do |time|
         
     | 
| 
      
 76 
     | 
    
         
            +
                      # @type var time: Float
         
     | 
| 
      
 77 
     | 
    
         
            +
                      # NOTE: time in <seconds> cuz Ruby's Timeout requires <seconds>
         
     | 
| 
      
 78 
     | 
    
         
            +
                      (time < 0) ? 0.0 : time
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                    # steep:ignore:end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    yield_with_timeout(
         
     | 
| 
      
 83 
     | 
    
         
            +
                      timeout,
         
     | 
| 
      
 84 
     | 
    
         
            +
                      lock_key,
         
     | 
| 
      
 85 
     | 
    
         
            +
                      ttl,
         
     | 
| 
      
 86 
     | 
    
         
            +
                      acquirer_id,
         
     | 
| 
      
 87 
     | 
    
         
            +
                      host_id,
         
     | 
| 
      
 88 
     | 
    
         
            +
                      meta,
         
     | 
| 
      
 89 
     | 
    
         
            +
                      &block # steep:ignore
         
     | 
| 
      
 90 
     | 
    
         
            +
                    )
         
     | 
| 
       70 
91 
     | 
    
         
             
                  else
         
     | 
| 
       71 
92 
     | 
    
         
             
                    yield
         
     | 
| 
       72 
93 
     | 
    
         
             
                  end
         
     | 
| 
       73 
94 
     | 
    
         
             
                end
         
     | 
| 
       74 
95 
     | 
    
         
             
              ensure
         
     | 
| 
       75 
     | 
    
         
            -
                if should_expire
         
     | 
| 
      
 96 
     | 
    
         
            +
                if should_expire # TODO: comment all cases/examples when should_expire is true
         
     | 
| 
       76 
97 
     | 
    
         
             
                  LogVisitor.expire_lock(
         
     | 
| 
       77 
98 
     | 
    
         
             
                    logger, log_sampled, lock_key,
         
     | 
| 
       78 
     | 
    
         
            -
                    queue_ttl,  
     | 
| 
      
 99 
     | 
    
         
            +
                    queue_ttl, acquirer_id, host_id, access_strategy
         
     | 
| 
       79 
100 
     | 
    
         
             
                  )
         
     | 
| 
       80 
101 
     | 
    
         
             
                  redis.call('EXPIRE', lock_key, '0')
         
     | 
| 
       81 
     | 
    
         
            -
                elsif should_decrease
         
     | 
| 
      
 102 
     | 
    
         
            +
                elsif should_decrease # TODO: comment all cases/examples when should_expire is true
         
     | 
| 
       82 
103 
     | 
    
         
             
                  finish_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  # @type var initial_time: Integer
         
     | 
| 
       83 
105 
     | 
    
         
             
                  spent_time = (finish_time - initial_time)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  # @type var ttl: Integer
         
     | 
| 
       84 
107 
     | 
    
         
             
                  decreased_ttl = ttl - spent_time - RedisQueuedLocks::Resource::REDIS_TIMESHIFT_ERROR
         
     | 
| 
       85 
108 
     | 
    
         | 
| 
       86 
109 
     | 
    
         
             
                  if decreased_ttl > 0
         
     | 
| 
       87 
110 
     | 
    
         
             
                    LogVisitor.decrease_lock(
         
     | 
| 
       88 
111 
     | 
    
         
             
                      logger, log_sampled, lock_key,
         
     | 
| 
       89 
     | 
    
         
            -
                      decreased_ttl, queue_ttl,  
     | 
| 
      
 112 
     | 
    
         
            +
                      decreased_ttl, queue_ttl, acquirer_id, host_id, access_strategy
         
     | 
| 
       90 
113 
     | 
    
         
             
                    )
         
     | 
| 
       91 
114 
     | 
    
         
             
                    # NOTE:# NOTE: EVAL signature -> <lua script>, (number of keys), *(keys), *(arguments)
         
     | 
| 
       92 
115 
     | 
    
         
             
                    redis.call('EVAL', DECREASE_LOCK_PTTL, 1, lock_key, decreased_ttl)
         
     | 
| 
         @@ -101,7 +124,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       101 
124 
     | 
    
         
             
              # @param timeout [Float]
         
     | 
| 
       102 
125 
     | 
    
         
             
              # @parma lock_key [String]
         
     | 
| 
       103 
126 
     | 
    
         
             
              # @param lock_ttl [Integer,NilClass]
         
     | 
| 
       104 
     | 
    
         
            -
              # @param  
     | 
| 
      
 127 
     | 
    
         
            +
              # @param acquirer_id [String]
         
     | 
| 
       105 
128 
     | 
    
         
             
              # @param host_id [String]
         
     | 
| 
       106 
129 
     | 
    
         
             
              # @param meta [NilClass,Hash<Symbol|String,Any>]
         
     | 
| 
       107 
130 
     | 
    
         
             
              # @param block [Blcok]
         
     | 
| 
         @@ -112,7 +135,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       112 
135 
     | 
    
         
             
              # @api private
         
     | 
| 
       113 
136 
     | 
    
         
             
              # @since 1.3.0
         
     | 
| 
       114 
137 
     | 
    
         
             
              # @version 1.12.0
         
     | 
| 
       115 
     | 
    
         
            -
              def yield_with_timeout(timeout, lock_key, lock_ttl,  
     | 
| 
      
 138 
     | 
    
         
            +
              def yield_with_timeout(timeout, lock_key, lock_ttl, acquirer_id, host_id, meta, &block)
         
     | 
| 
       116 
139 
     | 
    
         
             
                ::Timeout.timeout(timeout, RedisQueuedLocks::TimedLockIntermediateTimeoutError, &block)
         
     | 
| 
       117 
140 
     | 
    
         
             
              rescue RedisQueuedLocks::TimedLockIntermediateTimeoutError
         
     | 
| 
       118 
141 
     | 
    
         
             
                raise(
         
     | 
| 
         @@ -121,7 +144,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire 
     | 
|
| 
       121 
144 
     | 
    
         
             
                  "(lock: \"#{lock_key}\", " \
         
     | 
| 
       122 
145 
     | 
    
         
             
                  "ttl: #{lock_ttl}, " \
         
     | 
| 
       123 
146 
     | 
    
         
             
                  "meta: #{meta ? meta.inspect : '<no-meta>'}, " \
         
     | 
| 
       124 
     | 
    
         
            -
                  "acq_id: \"#{ 
     | 
| 
      
 147 
     | 
    
         
            +
                  "acq_id: \"#{acquirer_id}\", " \
         
     | 
| 
       125 
148 
     | 
    
         
             
                  "hst_id: \"#{host_id}\")"
         
     | 
| 
       126 
149 
     | 
    
         
             
                )
         
     | 
| 
       127 
150 
     | 
    
         
             
              end
         
     | 
| 
         @@ -8,7 +8,7 @@ 
     | 
|
| 
       8 
8 
     | 
    
         
             
            # rubocop:disable Metrics/ClassLength
         
     | 
| 
       9 
9 
     | 
    
         
             
            # rubocop:disable Metrics/BlockNesting
         
     | 
| 
       10 
10 
     | 
    
         
             
            # rubocop:disable Style/IfInsideElse
         
     | 
| 
       11 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 11 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::AcquireLock
         
     | 
| 
       12 
12 
     | 
    
         
             
              require_relative 'acquire_lock/log_visitor'
         
     | 
| 
       13 
13 
     | 
    
         
             
              require_relative 'acquire_lock/instr_visitor'
         
     | 
| 
       14 
14 
     | 
    
         
             
              require_relative 'acquire_lock/delay_execution'
         
     | 
| 
         @@ -17,6 +17,8 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       17 
17 
     | 
    
         
             
              require_relative 'acquire_lock/try_to_lock'
         
     | 
| 
       18 
18 
     | 
    
         
             
              require_relative 'acquire_lock/dequeue_from_lock_queue'
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
              # @since 1.14.0
         
     | 
| 
      
 21 
     | 
    
         
            +
              extend RedisQueuedLocks::Utilities
         
     | 
| 
       20 
22 
     | 
    
         
             
              # @since 1.0.0
         
     | 
| 
       21 
23 
     | 
    
         
             
              extend TryToLock
         
     | 
| 
       22 
24 
     | 
    
         
             
              # @since 1.0.0
         
     | 
| 
         @@ -32,7 +34,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       32 
34 
     | 
    
         
             
                # @param redis [RedisClient]
         
     | 
| 
       33 
35 
     | 
    
         
             
                #   Redis connection client.
         
     | 
| 
       34 
36 
     | 
    
         
             
                # @param lock_name [String]
         
     | 
| 
       35 
     | 
    
         
            -
                #   Lock name to be  
     | 
| 
      
 37 
     | 
    
         
            +
                #   Lock name to be acquirer.
         
     | 
| 
       36 
38 
     | 
    
         
             
                # @option process_id [Integer,String]
         
     | 
| 
       37 
39 
     | 
    
         
             
                #   The process that want to acquire a lock.
         
     | 
| 
       38 
40 
     | 
    
         
             
                # @option thread_id [Integer,String]
         
     | 
| 
         @@ -45,7 +47,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       45 
47 
     | 
    
         
             
                #   Lock's time to live (in milliseconds). Nil means "without timeout".
         
     | 
| 
       46 
48 
     | 
    
         
             
                # @option queue_ttl [Integer]
         
     | 
| 
       47 
49 
     | 
    
         
             
                #   Lifetime of the acuier's lock request. In seconds.
         
     | 
| 
       48 
     | 
    
         
            -
                # @option timeout [Integer]
         
     | 
| 
      
 50 
     | 
    
         
            +
                # @option timeout [Integer,NilClass]
         
     | 
| 
       49 
51 
     | 
    
         
             
                #   Time period whe should try to acquire the lock (in seconds).
         
     | 
| 
       50 
52 
     | 
    
         
             
                # @option timed [Boolean]
         
     | 
| 
       51 
53 
     | 
    
         
             
                #   Limit the invocation time period of the passed block of code by the lock's TTL.
         
     | 
| 
         @@ -72,15 +74,15 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       72 
74 
     | 
    
         
             
                # @option detailed_acq_timeout_error [Boolean]
         
     | 
| 
       73 
75 
     | 
    
         
             
                #   - Add additional data to the acquirement timeout error such as the current lock queue state
         
     | 
| 
       74 
76 
     | 
    
         
             
                #   and the required lock state;
         
     | 
| 
       75 
     | 
    
         
            -
                #   - See `config[ 
     | 
| 
      
 77 
     | 
    
         
            +
                #   - See `config['detailed_acq_timeout_error']` for details;
         
     | 
| 
       76 
78 
     | 
    
         
             
                # @option logger [::Logger,#debug]
         
     | 
| 
       77 
     | 
    
         
            -
                #   - Logger object used from the configuration layer (see config[ 
     | 
| 
      
 79 
     | 
    
         
            +
                #   - Logger object used from the configuration layer (see config['logger']);
         
     | 
| 
       78 
80 
     | 
    
         
             
                #   - See `RedisQueuedLocks::Logging::VoidLogger` for example;
         
     | 
| 
       79 
81 
     | 
    
         
             
                #   - Supports `SemanticLogger::Logger` (see "semantic_logger" gem)
         
     | 
| 
       80 
82 
     | 
    
         
             
                # @option log_lock_try [Boolean]
         
     | 
| 
       81 
83 
     | 
    
         
             
                #   - should be logged the each try of lock acquiring (a lot of logs can be generated depending
         
     | 
| 
       82 
84 
     | 
    
         
             
                #     on your retry configurations);
         
     | 
| 
       83 
     | 
    
         
            -
                #   - see `config[ 
     | 
| 
      
 85 
     | 
    
         
            +
                #   - see `config['log_lock_try']`;
         
     | 
| 
       84 
86 
     | 
    
         
             
                # @option instrument [NilClass,Any]
         
     | 
| 
       85 
87 
     | 
    
         
             
                #   - Custom instrumentation data wich will be passed to the instrumenter's payload
         
     | 
| 
       86 
88 
     | 
    
         
             
                #     with :instrument key;
         
     | 
| 
         @@ -88,12 +90,14 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       88 
90 
     | 
    
         
             
                #   - The conflict strategy mode for cases when the process that obtained the lock
         
     | 
| 
       89 
91 
     | 
    
         
             
                #     want to acquire this lock again;
         
     | 
| 
       90 
92 
     | 
    
         
             
                #   - By default uses `:wait_for_lock` strategy;
         
     | 
| 
       91 
     | 
    
         
            -
                #   - pre-confured in `config[ 
     | 
| 
      
 93 
     | 
    
         
            +
                #   - pre-confured in `config['default_conflict_strategy']`;
         
     | 
| 
       92 
94 
     | 
    
         
             
                #   - Supports:
         
     | 
| 
       93 
95 
     | 
    
         
             
                #     - `:work_through`;
         
     | 
| 
       94 
96 
     | 
    
         
             
                #     - `:extendable_work_through`;
         
     | 
| 
       95 
97 
     | 
    
         
             
                #     - `:wait_for_lock`;
         
     | 
| 
       96 
98 
     | 
    
         
             
                #     - `:dead_locking`;
         
     | 
| 
      
 99 
     | 
    
         
            +
                # @option read_write_mode [Symbol]
         
     | 
| 
      
 100 
     | 
    
         
            +
                #   - ?
         
     | 
| 
       97 
101 
     | 
    
         
             
                # @option access_strategy [Symbol]
         
     | 
| 
       98 
102 
     | 
    
         
             
                #   - The way in which the lock will be obtained;
         
     | 
| 
       99 
103 
     | 
    
         
             
                #   - By default it uses `:queued` strategy;
         
     | 
| 
         @@ -103,19 +107,19 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       103 
107 
     | 
    
         
             
                #     - `:random` (RANDOM): obtain a lock without checking the positions in the queue
         
     | 
| 
       104 
108 
     | 
    
         
             
                #       (but with checking the limist, retries, timeouts and so on). if lock is
         
     | 
| 
       105 
109 
     | 
    
         
             
                #       free to obtain - it will be obtained;
         
     | 
| 
       106 
     | 
    
         
            -
                #   - pre-configured in `config[ 
     | 
| 
      
 110 
     | 
    
         
            +
                #   - pre-configured in `config['default_access_strategy']`;
         
     | 
| 
       107 
111 
     | 
    
         
             
                # @option log_sampling_enabled [Boolean]
         
     | 
| 
       108 
112 
     | 
    
         
             
                #   - enables <log sampling>: only the configured percent of RQL cases will be logged;
         
     | 
| 
       109 
113 
     | 
    
         
             
                #   - disabled by default;
         
     | 
| 
       110 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
      
 114 
     | 
    
         
            +
                #   - works in tandem with <config['log_sampling_percent'] and <config['log_sampler']>;
         
     | 
| 
       111 
115 
     | 
    
         
             
                # @option log_sampling_percent [Integer]
         
     | 
| 
       112 
116 
     | 
    
         
             
                #   - the percent of cases that should be logged;
         
     | 
| 
       113 
     | 
    
         
            -
                #   - take an effect when <config 
     | 
| 
       114 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
      
 117 
     | 
    
         
            +
                #   - take an effect when <config['log_sampling_enalbed']> is true;
         
     | 
| 
      
 118 
     | 
    
         
            +
                #   - works in tandem with <config['log_sampling_enabled']> and <config['log_sampler']> configs;
         
     | 
| 
       115 
119 
     | 
    
         
             
                # @option log_sampler [#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]
         
     | 
| 
       116 
120 
     | 
    
         
             
                #   - percent-based log sampler that decides should be RQL case logged or not;
         
     | 
| 
       117 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
       118 
     | 
    
         
            -
                #     <config 
     | 
| 
      
 121 
     | 
    
         
            +
                #   - works in tandem with <config['log_sampling_enabled']> and
         
     | 
| 
      
 122 
     | 
    
         
            +
                #     <config['log_sampling_percent']> configs;
         
     | 
| 
       119 
123 
     | 
    
         
             
                #   - based on the ultra simple percent-based (weight-based) algorithm that uses
         
     | 
| 
       120 
124 
     | 
    
         
             
                #     SecureRandom.rand method so the algorithm error is ~(0%..13%);
         
     | 
| 
       121 
125 
     | 
    
         
             
                #   - you can provide your own log sampler with bettter algorithm that should realize
         
     | 
| 
         @@ -128,15 +132,16 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       128 
132 
     | 
    
         
             
                #   - enables <instrumentaion sampling>: only the configured percent
         
     | 
| 
       129 
133 
     | 
    
         
             
                #     of RQL cases will be instrumented;
         
     | 
| 
       130 
134 
     | 
    
         
             
                #   - disabled by default;
         
     | 
| 
       131 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
      
 135 
     | 
    
         
            +
                #   - works in tandem with <config['instr_sampling_percent']> and <config['instr_sampler']>;
         
     | 
| 
       132 
136 
     | 
    
         
             
                # @option instr_sampling_percent [Integer]
         
     | 
| 
       133 
137 
     | 
    
         
             
                #   - the percent of cases that should be instrumented;
         
     | 
| 
       134 
     | 
    
         
            -
                #   - take an effect when <config 
     | 
| 
       135 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
      
 138 
     | 
    
         
            +
                #   - take an effect when <config['instr_sampling_enalbed']> is true;
         
     | 
| 
      
 139 
     | 
    
         
            +
                #   - works in tandem with <config['instr_sampling_enabled']>
         
     | 
| 
      
 140 
     | 
    
         
            +
                #     and <config['instr_sampler']> configs;
         
     | 
| 
       136 
141 
     | 
    
         
             
                # @option instr_sampler [#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]
         
     | 
| 
       137 
142 
     | 
    
         
             
                #   - percent-based log sampler that decides should be RQL case instrumented or not;
         
     | 
| 
       138 
     | 
    
         
            -
                #   - works in tandem with <config 
     | 
| 
       139 
     | 
    
         
            -
                #     <config 
     | 
| 
      
 143 
     | 
    
         
            +
                #   - works in tandem with <config['instr_sampling_enabled']> and
         
     | 
| 
      
 144 
     | 
    
         
            +
                #     <config['instr_sampling_percent']> configs;
         
     | 
| 
       140 
145 
     | 
    
         
             
                #   - based on the ultra simple percent-based (weight-based) algorithm that uses
         
     | 
| 
       141 
146 
     | 
    
         
             
                #     SecureRandom.rand method so the algorithm error is ~(0%..13%);
         
     | 
| 
       142 
147 
     | 
    
         
             
                #   - you can provide your own log sampler with bettter algorithm that should realize
         
     | 
| 
         @@ -148,13 +153,13 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       148 
153 
     | 
    
         
             
                #   - makes sense when instrumentation sampling is enabled;
         
     | 
| 
       149 
154 
     | 
    
         
             
                # @param [Block]
         
     | 
| 
       150 
155 
     | 
    
         
             
                #   A block of code that should be executed after the successfully acquired lock.
         
     | 
| 
       151 
     | 
    
         
            -
                # @return [ 
     | 
| 
      
 156 
     | 
    
         
            +
                # @return [Hash<Symbol,Any>,yield]
         
     | 
| 
       152 
157 
     | 
    
         
             
                #  - Format: { ok: true/false, result: Any }
         
     | 
| 
       153 
158 
     | 
    
         
             
                #  - If block is given the result of block's yeld will be returned.
         
     | 
| 
       154 
159 
     | 
    
         
             
                #
         
     | 
| 
       155 
160 
     | 
    
         
             
                # @api private
         
     | 
| 
       156 
161 
     | 
    
         
             
                # @since 1.0.0
         
     | 
| 
       157 
     | 
    
         
            -
                # @version 1. 
     | 
| 
      
 162 
     | 
    
         
            +
                # @version 1.14.0
         
     | 
| 
       158 
163 
     | 
    
         
             
                def acquire_lock(
         
     | 
| 
       159 
164 
     | 
    
         
             
                  redis,
         
     | 
| 
       160 
165 
     | 
    
         
             
                  lock_name,
         
     | 
| 
         @@ -179,6 +184,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       179 
184 
     | 
    
         
             
                  logger:,
         
     | 
| 
       180 
185 
     | 
    
         
             
                  log_lock_try:,
         
     | 
| 
       181 
186 
     | 
    
         
             
                  conflict_strategy:,
         
     | 
| 
      
 187 
     | 
    
         
            +
                  read_write_mode:,
         
     | 
| 
       182 
188 
     | 
    
         
             
                  access_strategy:,
         
     | 
| 
       183 
189 
     | 
    
         
             
                  log_sampling_enabled:,
         
     | 
| 
       184 
190 
     | 
    
         
             
                  log_sampling_percent:,
         
     | 
| 
         @@ -224,7 +230,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       224 
230 
     | 
    
         
             
                  end
         
     | 
| 
       225 
231 
     | 
    
         | 
| 
       226 
232 
     | 
    
         
             
                  # Step 1: prepare lock requirements (generate lock name, calc lock ttl, etc).
         
     | 
| 
       227 
     | 
    
         
            -
                   
     | 
| 
      
 233 
     | 
    
         
            +
                  acquirer_id = RedisQueuedLocks::Resource.acquirer_identifier(
         
     | 
| 
       228 
234 
     | 
    
         
             
                    process_id,
         
     | 
| 
       229 
235 
     | 
    
         
             
                    thread_id,
         
     | 
| 
       230 
236 
     | 
    
         
             
                    fiber_id,
         
     | 
| 
         @@ -240,7 +246,11 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       240 
246 
     | 
    
         
             
                  lock_ttl = ttl
         
     | 
| 
       241 
247 
     | 
    
         
             
                  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
         
     | 
| 
       242 
248 
     | 
    
         
             
                  lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
         
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                  read_lock_key_queue = RedisQueuedLocks::Resource.prepare_read_lock_queue(lock_name)
         
     | 
| 
      
 251 
     | 
    
         
            +
                  write_lock_key_queue = RedisQueuedLocks::Resource.prepare_write_lock_queue(lock_name)
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
                  acquirer_position = RedisQueuedLocks::Resource.calc_initial_acquirer_position
         
     | 
| 
       244 
254 
     | 
    
         | 
| 
       245 
255 
     | 
    
         
             
                  log_sampled = RedisQueuedLocks::Logging.should_log?(
         
     | 
| 
       246 
256 
     | 
    
         
             
                    log_sampling_enabled,
         
     | 
| 
         @@ -256,6 +266,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       256 
266 
     | 
    
         
             
                  )
         
     | 
| 
       257 
267 
     | 
    
         | 
| 
       258 
268 
     | 
    
         
             
                  # Step X: intermediate result observer
         
     | 
| 
      
 269 
     | 
    
         
            +
                  # @type var acq_process: Hash[Symbol,untyped]
         
     | 
| 
       259 
270 
     | 
    
         
             
                  acq_process = {
         
     | 
| 
       260 
271 
     | 
    
         
             
                    lock_info: {},
         
     | 
| 
       261 
272 
     | 
    
         
             
                    should_try: true,
         
     | 
| 
         @@ -272,9 +283,12 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       272 
283 
     | 
    
         
             
                      redis,
         
     | 
| 
       273 
284 
     | 
    
         
             
                      logger,
         
     | 
| 
       274 
285 
     | 
    
         
             
                      lock_key,
         
     | 
| 
      
 286 
     | 
    
         
            +
                      read_write_mode,
         
     | 
| 
       275 
287 
     | 
    
         
             
                      lock_key_queue,
         
     | 
| 
      
 288 
     | 
    
         
            +
                      read_lock_key_queue,
         
     | 
| 
      
 289 
     | 
    
         
            +
                      write_lock_key_queue,
         
     | 
| 
       276 
290 
     | 
    
         
             
                      queue_ttl,
         
     | 
| 
       277 
     | 
    
         
            -
                       
     | 
| 
      
 291 
     | 
    
         
            +
                      acquirer_id,
         
     | 
| 
       278 
292 
     | 
    
         
             
                      host_id,
         
     | 
| 
       279 
293 
     | 
    
         
             
                      access_strategy,
         
     | 
| 
       280 
294 
     | 
    
         
             
                      log_sampled,
         
     | 
| 
         @@ -284,7 +298,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       284 
298 
     | 
    
         | 
| 
       285 
299 
     | 
    
         
             
                  LogVisitor.start_lock_obtaining(
         
     | 
| 
       286 
300 
     | 
    
         
             
                    logger, log_sampled, lock_key,
         
     | 
| 
       287 
     | 
    
         
            -
                    queue_ttl,  
     | 
| 
      
 301 
     | 
    
         
            +
                    queue_ttl, acquirer_id, host_id, access_strategy
         
     | 
| 
       288 
302 
     | 
    
         
             
                  )
         
     | 
| 
       289 
303 
     | 
    
         | 
| 
       290 
304 
     | 
    
         
             
                  # Step 2: try to lock with timeout
         
     | 
| 
         @@ -297,36 +311,41 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       297 
311 
     | 
    
         
             
                    detailed_acq_timeout_error,
         
     | 
| 
       298 
312 
     | 
    
         
             
                    on_timeout: acq_dequeue
         
     | 
| 
       299 
313 
     | 
    
         
             
                  ) do
         
     | 
| 
       300 
     | 
    
         
            -
                    acq_start_time =  
     | 
| 
      
 314 
     | 
    
         
            +
                    acq_start_time = clock_gettime
         
     | 
| 
       301 
315 
     | 
    
         | 
| 
       302 
316 
     | 
    
         
             
                    # Step 2.1: cyclically try to obtain the lock
         
     | 
| 
       303 
317 
     | 
    
         
             
                    while acq_process[:should_try]
         
     | 
| 
       304 
318 
     | 
    
         | 
| 
       305 
319 
     | 
    
         
             
                      LogVisitor.start_try_to_lock_cycle(
         
     | 
| 
       306 
320 
     | 
    
         
             
                        logger, log_sampled, lock_key,
         
     | 
| 
       307 
     | 
    
         
            -
                        queue_ttl,  
     | 
| 
      
 321 
     | 
    
         
            +
                        queue_ttl, acquirer_id, host_id, access_strategy
         
     | 
| 
       308 
322 
     | 
    
         
             
                      )
         
     | 
| 
       309 
323 
     | 
    
         | 
| 
       310 
324 
     | 
    
         
             
                      # Step 2.X: check the actual score: is it in queue ttl limit or not?
         
     | 
| 
       311 
     | 
    
         
            -
                      if RedisQueuedLocks::Resource.dead_score_reached?( 
     | 
| 
      
 325 
     | 
    
         
            +
                      if RedisQueuedLocks::Resource.dead_score_reached?(acquirer_position, queue_ttl)
         
     | 
| 
       312 
326 
     | 
    
         
             
                        # Step 2.X.X: dead score reached => re-queue the lock request with the new score;
         
     | 
| 
       313 
     | 
    
         
            -
                         
     | 
| 
      
 327 
     | 
    
         
            +
                        acquirer_position = RedisQueuedLocks::Resource.calc_initial_acquirer_position
         
     | 
| 
       314 
328 
     | 
    
         | 
| 
       315 
     | 
    
         
            -
                        LogVisitor. 
     | 
| 
      
 329 
     | 
    
         
            +
                        LogVisitor.dead_score_reached__reset_acquirer_position(
         
     | 
| 
       316 
330 
     | 
    
         
             
                          logger, log_sampled, lock_key,
         
     | 
| 
       317 
     | 
    
         
            -
                          queue_ttl,  
     | 
| 
      
 331 
     | 
    
         
            +
                          queue_ttl, acquirer_id, host_id, access_strategy
         
     | 
| 
       318 
332 
     | 
    
         
             
                        )
         
     | 
| 
       319 
333 
     | 
    
         
             
                      end
         
     | 
| 
       320 
334 
     | 
    
         | 
| 
      
 335 
     | 
    
         
            +
                      # NOTE: (steep ignorance) pattern matching is not supported in steep
         
     | 
| 
      
 336 
     | 
    
         
            +
                      # steep:ignore:start
         
     | 
| 
       321 
337 
     | 
    
         
             
                      try_to_lock(
         
     | 
| 
       322 
338 
     | 
    
         
             
                        redis,
         
     | 
| 
       323 
339 
     | 
    
         
             
                        logger,
         
     | 
| 
       324 
340 
     | 
    
         
             
                        log_lock_try,
         
     | 
| 
       325 
341 
     | 
    
         
             
                        lock_key,
         
     | 
| 
      
 342 
     | 
    
         
            +
                        read_write_mode,
         
     | 
| 
       326 
343 
     | 
    
         
             
                        lock_key_queue,
         
     | 
| 
       327 
     | 
    
         
            -
                         
     | 
| 
      
 344 
     | 
    
         
            +
                        read_lock_key_queue,
         
     | 
| 
      
 345 
     | 
    
         
            +
                        write_lock_key_queue,
         
     | 
| 
      
 346 
     | 
    
         
            +
                        acquirer_id,
         
     | 
| 
       328 
347 
     | 
    
         
             
                        host_id,
         
     | 
| 
       329 
     | 
    
         
            -
                         
     | 
| 
      
 348 
     | 
    
         
            +
                        acquirer_position,
         
     | 
| 
       330 
349 
     | 
    
         
             
                        lock_ttl,
         
     | 
| 
       331 
350 
     | 
    
         
             
                        queue_ttl,
         
     | 
| 
       332 
351 
     | 
    
         
             
                        fail_fast,
         
     | 
| 
         @@ -336,8 +355,12 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       336 
355 
     | 
    
         
             
                        log_sampled,
         
     | 
| 
       337 
356 
     | 
    
         
             
                        instr_sampled
         
     | 
| 
       338 
357 
     | 
    
         
             
                      ) => { ok:, result: }
         
     | 
| 
      
 358 
     | 
    
         
            +
                      # steep:ignore:end
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
                      # @type var ok: bool
         
     | 
| 
      
 361 
     | 
    
         
            +
                      # @type var result: Symbol|Hash[Symbol,untyped]
         
     | 
| 
       339 
362 
     | 
    
         | 
| 
       340 
     | 
    
         
            -
                      acq_end_time =  
     | 
| 
      
 363 
     | 
    
         
            +
                      acq_end_time = clock_gettime
         
     | 
| 
       341 
364 
     | 
    
         
             
                      acq_time = ((acq_end_time - acq_start_time) / 1_000.0).ceil(2)
         
     | 
| 
       342 
365 
     | 
    
         | 
| 
       343 
366 
     | 
    
         
             
                      # Step X: save the intermediate results to the result observer
         
     | 
| 
         @@ -346,12 +369,14 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       346 
369 
     | 
    
         | 
| 
       347 
370 
     | 
    
         
             
                      # Step 2.1: analyze an acquirement attempt
         
     | 
| 
       348 
371 
     | 
    
         
             
                      if ok
         
     | 
| 
      
 372 
     | 
    
         
            +
                        # @type var result: Hash[Symbol,untyped]
         
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
       349 
374 
     | 
    
         
             
                        # Step X: (instrumentation)
         
     | 
| 
       350 
375 
     | 
    
         
             
                        if acq_process[:result][:process] == :extendable_conflict_work_through
         
     | 
| 
       351 
376 
     | 
    
         
             
                          # instrumetnation: (reentrant lock with ttl extension)
         
     | 
| 
       352 
377 
     | 
    
         
             
                          LogVisitor.extendable_reentrant_lock_obtained(
         
     | 
| 
       353 
378 
     | 
    
         
             
                            logger, log_sampled, result[:lock_key],
         
     | 
| 
       354 
     | 
    
         
            -
                            queue_ttl,  
     | 
| 
      
 379 
     | 
    
         
            +
                            queue_ttl, acquirer_id, host_id, acq_time, access_strategy
         
     | 
| 
       355 
380 
     | 
    
         
             
                          )
         
     | 
| 
       356 
381 
     | 
    
         
             
                          InstrVisitor.extendable_reentrant_lock_obtained(
         
     | 
| 
       357 
382 
     | 
    
         
             
                            instrumenter, instr_sampled, result[:lock_key],
         
     | 
| 
         @@ -362,7 +387,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       362 
387 
     | 
    
         
             
                          # instrumetnation: (reentrant lock without ttl extension)
         
     | 
| 
       363 
388 
     | 
    
         
             
                          LogVisitor.reentrant_lock_obtained(
         
     | 
| 
       364 
389 
     | 
    
         
             
                            logger, log_sampled, result[:lock_key],
         
     | 
| 
       365 
     | 
    
         
            -
                            queue_ttl,  
     | 
| 
      
 390 
     | 
    
         
            +
                            queue_ttl, acquirer_id, host_id, acq_time, access_strategy
         
     | 
| 
       366 
391 
     | 
    
         
             
                          )
         
     | 
| 
       367 
392 
     | 
    
         
             
                          InstrVisitor.reentrant_lock_obtained(
         
     | 
| 
       368 
393 
     | 
    
         
             
                            instrumenter, instr_sampled, result[:lock_key],
         
     | 
| 
         @@ -374,7 +399,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       374 
399 
     | 
    
         
             
                          # NOTE: classic is: acq_process[:result][:process] == :lock_obtaining
         
     | 
| 
       375 
400 
     | 
    
         
             
                          LogVisitor.lock_obtained(
         
     | 
| 
       376 
401 
     | 
    
         
             
                            logger, log_sampled, result[:lock_key],
         
     | 
| 
       377 
     | 
    
         
            -
                            queue_ttl,  
     | 
| 
      
 402 
     | 
    
         
            +
                            queue_ttl, acquirer_id, host_id, acq_time, access_strategy
         
     | 
| 
       378 
403 
     | 
    
         
             
                          )
         
     | 
| 
       379 
404 
     | 
    
         
             
                          InstrVisitor.lock_obtained(
         
     | 
| 
       380 
405 
     | 
    
         
             
                            instrumenter, instr_sampled, result[:lock_key],
         
     | 
| 
         @@ -397,6 +422,8 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       397 
422 
     | 
    
         
             
                        acq_process[:acq_time] = acq_time
         
     | 
| 
       398 
423 
     | 
    
         
             
                        acq_process[:acq_end_time] = acq_end_time
         
     | 
| 
       399 
424 
     | 
    
         
             
                      else
         
     | 
| 
      
 425 
     | 
    
         
            +
                        # @type var result: Symbol
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
       400 
427 
     | 
    
         
             
                        # Step 2.2: failed to acquire. anylize each case and act in accordance
         
     | 
| 
       401 
428 
     | 
    
         
             
                        if acq_process[:result] == :fail_fast_no_try # Step 2.2.a: fail without try
         
     | 
| 
       402 
429 
     | 
    
         
             
                          acq_process[:should_try] = false
         
     | 
| 
         @@ -415,9 +442,9 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       415 
442 
     | 
    
         | 
| 
       416 
443 
     | 
    
         
             
                          if raise_errors
         
     | 
| 
       417 
444 
     | 
    
         
             
                            raise(
         
     | 
| 
       418 
     | 
    
         
            -
                               
     | 
| 
      
 445 
     | 
    
         
            +
                              RedisQueuedLocks::ConflictLockObtainError,
         
     | 
| 
       419 
446 
     | 
    
         
             
                              "Lock Conflict: trying to acquire the lock \"#{lock_key}\" " \
         
     | 
| 
       420 
     | 
    
         
            -
                              "that is already acquired by the current  
     | 
| 
      
 447 
     | 
    
         
            +
                              "that is already acquired by the current acquirer (acq_id: \"#{acquirer_id}\")."
         
     | 
| 
       421 
448 
     | 
    
         
             
                            )
         
     | 
| 
       422 
449 
     | 
    
         
             
                          end
         
     | 
| 
       423 
450 
     | 
    
         
             
                        else
         
     | 
| 
         @@ -443,7 +470,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       443 
470 
     | 
    
         | 
| 
       444 
471 
     | 
    
         
             
                              if raise_errors
         
     | 
| 
       445 
472 
     | 
    
         
             
                                raise(
         
     | 
| 
       446 
     | 
    
         
            -
                                  RedisQueuedLocks:: 
     | 
| 
      
 473 
     | 
    
         
            +
                                  RedisQueuedLocks::LockAcquirementRetryLimitError,
         
     | 
| 
       447 
474 
     | 
    
         
             
                                  "Failed to acquire the lock \"#{lock_key}\" " \
         
     | 
| 
       448 
475 
     | 
    
         
             
                                  "for the given retry_count limit (#{retry_count} times)."
         
     | 
| 
       449 
476 
     | 
    
         
             
                                )
         
     | 
| 
         @@ -466,7 +493,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       466 
493 
     | 
    
         
             
                    # Step 3.a: acquired successfully => run logic or return the result of acquirement
         
     | 
| 
       467 
494 
     | 
    
         
             
                    if block_given?
         
     | 
| 
       468 
495 
     | 
    
         
             
                      begin
         
     | 
| 
       469 
     | 
    
         
            -
                        yield_time =  
     | 
| 
      
 496 
     | 
    
         
            +
                        yield_time = clock_gettime
         
     | 
| 
       470 
497 
     | 
    
         | 
| 
       471 
498 
     | 
    
         
             
                        ttl_shift = (
         
     | 
| 
       472 
499 
     | 
    
         
             
                          (yield_time - acq_process[:acq_end_time]) / 1_000.0 -
         
     | 
| 
         @@ -484,7 +511,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       484 
511 
     | 
    
         
             
                          redis,
         
     | 
| 
       485 
512 
     | 
    
         
             
                          logger,
         
     | 
| 
       486 
513 
     | 
    
         
             
                          lock_key,
         
     | 
| 
       487 
     | 
    
         
            -
                           
     | 
| 
      
 514 
     | 
    
         
            +
                          acquirer_id,
         
     | 
| 
       488 
515 
     | 
    
         
             
                          host_id,
         
     | 
| 
       489 
516 
     | 
    
         
             
                          access_strategy,
         
     | 
| 
       490 
517 
     | 
    
         
             
                          timed,
         
     | 
| 
         @@ -499,9 +526,7 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       499 
526 
     | 
    
         
             
                          &block
         
     | 
| 
       500 
527 
     | 
    
         
             
                        )
         
     | 
| 
       501 
528 
     | 
    
         
             
                      ensure
         
     | 
| 
       502 
     | 
    
         
            -
                        acq_process[:rel_time] =  
     | 
| 
       503 
     | 
    
         
            -
                          ::Process::CLOCK_MONOTONIC, :microsecond
         
     | 
| 
       504 
     | 
    
         
            -
                        )
         
     | 
| 
      
 529 
     | 
    
         
            +
                        acq_process[:rel_time] = clock_gettime
         
     | 
| 
       505 
530 
     | 
    
         
             
                        acq_process[:hold_time] = (
         
     | 
| 
       506 
531 
     | 
    
         
             
                          (acq_process[:rel_time] - acq_process[:acq_end_time]) / 1_000.0
         
     | 
| 
       507 
532 
     | 
    
         
             
                        ).ceil(2)
         
     | 
| 
         @@ -538,7 +563,9 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       538 
563 
     | 
    
         
             
                        end
         
     | 
| 
       539 
564 
     | 
    
         
             
                      end
         
     | 
| 
       540 
565 
     | 
    
         
             
                    else
         
     | 
| 
       541 
     | 
    
         
            -
                       
     | 
| 
      
 566 
     | 
    
         
            +
                      # rubocop:disable Layout/LineLength
         
     | 
| 
      
 567 
     | 
    
         
            +
                      { ok: true, result: acq_process[:lock_info] } #: { ok: bool, result: Hash[Symbol,untyped] }
         
     | 
| 
      
 568 
     | 
    
         
            +
                      # rubocop:enable Layout/LineLength
         
     | 
| 
       542 
569 
     | 
    
         
             
                    end
         
     | 
| 
       543 
570 
     | 
    
         
             
                  else
         
     | 
| 
       544 
571 
     | 
    
         
             
                    if acq_process[:result] != :retry_limit_reached &&
         
     | 
| 
         @@ -551,8 +578,8 @@ module RedisQueuedLocks::Acquier::AcquireLock 
     | 
|
| 
       551 
578 
     | 
    
         
             
                      #   - **(notice: in other cases the lock obtaining time and tries count are infinite)
         
     | 
| 
       552 
579 
     | 
    
         
             
                      acq_process[:result] = :timeout_reached
         
     | 
| 
       553 
580 
     | 
    
         
             
                    end
         
     | 
| 
       554 
     | 
    
         
            -
                    # Step 3.b: lock is not acquired ( 
     | 
| 
       555 
     | 
    
         
            -
                     
     | 
| 
      
 581 
     | 
    
         
            +
                    # Step 3.b: lock is not acquired (acquirer is dequeued by timeout callback)
         
     | 
| 
      
 582 
     | 
    
         
            +
                    { ok: false, result: acq_process[:result] } #: { ok: bool, result: Symbol }
         
     | 
| 
       556 
583 
     | 
    
         
             
                  end
         
     | 
| 
       557 
584 
     | 
    
         
             
                end
         
     | 
| 
       558 
585 
     | 
    
         
             
              end
         
     | 
| 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # @api private
         
     | 
| 
       4 
4 
     | 
    
         
             
            # @since 1.0.0
         
     | 
| 
       5 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 5 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::ClearDeadRequests
         
     | 
| 
       6 
6 
     | 
    
         
             
              class << self
         
     | 
| 
       7 
7 
     | 
    
         
             
                # @param redis_client [RedisClient]
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @param scan_size [Integer]
         
     | 
| 
         @@ -39,9 +39,11 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests 
     | 
|
| 
       39 
39 
     | 
    
         
             
                  instr_sampler,
         
     | 
| 
       40 
40 
     | 
    
         
             
                  instr_sample_this
         
     | 
| 
       41 
41 
     | 
    
         
             
                )
         
     | 
| 
       42 
     | 
    
         
            -
                  dead_score = RedisQueuedLocks::Resource. 
     | 
| 
      
 42 
     | 
    
         
            +
                  dead_score = RedisQueuedLocks::Resource.acquirer_dead_score(dead_ttl / 1_000.0)
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
      
 44 
     | 
    
         
            +
                  # @type var result: Set[String]
         
     | 
| 
       44 
45 
     | 
    
         
             
                  result = Set.new.tap do |processed_queues|
         
     | 
| 
      
 46 
     | 
    
         
            +
                    # @type var processed_queues: Set[String]
         
     | 
| 
       45 
47 
     | 
    
         
             
                    redis_client.with do |rconn|
         
     | 
| 
       46 
48 
     | 
    
         
             
                      each_lock_queue(rconn, scan_size) do |lock_queue|
         
     | 
| 
       47 
49 
     | 
    
         
             
                        rconn.call('ZREMRANGEBYSCORE', lock_queue, '-inf', dead_score)
         
     | 
| 
         @@ -50,7 +52,7 @@ module RedisQueuedLocks::Acquier::ClearDeadRequests 
     | 
|
| 
       50 
52 
     | 
    
         
             
                    end
         
     | 
| 
       51 
53 
     | 
    
         
             
                  end
         
     | 
| 
       52 
54 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
      
 55 
     | 
    
         
            +
                  { ok: true, result: { processed_queues: result } }
         
     | 
| 
       54 
56 
     | 
    
         
             
                end
         
     | 
| 
       55 
57 
     | 
    
         | 
| 
       56 
58 
     | 
    
         
             
                private
         
     | 
| 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # @api private
         
     | 
| 
       4 
4 
     | 
    
         
             
            # @since 1.0.0
         
     | 
| 
       5 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 5 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::ExtendLockTTL
         
     | 
| 
       6 
6 
     | 
    
         
             
              # @return [String]
         
     | 
| 
       7 
7 
     | 
    
         
             
              #
         
     | 
| 
       8 
8 
     | 
    
         
             
              # @api private
         
     | 
| 
         @@ -54,10 +54,11 @@ module RedisQueuedLocks::Acquier::ExtendLockTTL 
     | 
|
| 
       54 
54 
     | 
    
         
             
                  result = redis_client.call('EVAL', EXTEND_LOCK_PTTL, 1, lock_key, milliseconds)
         
     | 
| 
       55 
55 
     | 
    
         
             
                  # TODO: upload scripts to the redis
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
                  # @type var result: Integer
         
     | 
| 
       57 
58 
     | 
    
         
             
                  if result == 1
         
     | 
| 
       58 
     | 
    
         
            -
                     
     | 
| 
      
 59 
     | 
    
         
            +
                    { ok: true, result: :ttl_extended }
         
     | 
| 
       59 
60 
     | 
    
         
             
                  else
         
     | 
| 
       60 
     | 
    
         
            -
                     
     | 
| 
      
 61 
     | 
    
         
            +
                    { ok: false, result: :async_expire_or_no_lock }
         
     | 
| 
       61 
62 
     | 
    
         
             
                  end
         
     | 
| 
       62 
63 
     | 
    
         
             
                end
         
     | 
| 
       63 
64 
     | 
    
         
             
              end
         
     | 
| 
         @@ -2,23 +2,23 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # @api private
         
     | 
| 
       4 
4 
     | 
    
         
             
            # @since 1.0.0
         
     | 
| 
       5 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 5 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::Keys
         
     | 
| 
       6 
6 
     | 
    
         
             
              class << self
         
     | 
| 
       7 
7 
     | 
    
         
             
                # @param redis_client [RedisClient]
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @option scan_size [Integer]
         
     | 
| 
       9 
     | 
    
         
            -
                # @return [ 
     | 
| 
      
 9 
     | 
    
         
            +
                # @return [Set<String>]
         
     | 
| 
       10 
10 
     | 
    
         
             
                #
         
     | 
| 
       11 
11 
     | 
    
         
             
                # @api private
         
     | 
| 
       12 
12 
     | 
    
         
             
                # @since 1.0.0
         
     | 
| 
       13 
13 
     | 
    
         
             
                def keys(redis_client, scan_size:)
         
     | 
| 
       14 
     | 
    
         
            -
                  Set.new.tap do | 
     | 
| 
      
 14 
     | 
    
         
            +
                  Set.new.tap do |keyset|
         
     | 
| 
      
 15 
     | 
    
         
            +
                    # @type var keyset: Set[String]
         
     | 
| 
       15 
16 
     | 
    
         
             
                    redis_client.scan(
         
     | 
| 
       16 
17 
     | 
    
         
             
                      'MATCH',
         
     | 
| 
       17 
18 
     | 
    
         
             
                      RedisQueuedLocks::Resource::KEY_PATTERN,
         
     | 
| 
       18 
19 
     | 
    
         
             
                      count: scan_size
         
     | 
| 
       19 
20 
     | 
    
         
             
                    ) do |key|
         
     | 
| 
       20 
     | 
    
         
            -
                       
     | 
| 
       21 
     | 
    
         
            -
                      keys.add(key)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      keyset.add(key)
         
     | 
| 
       22 
22 
     | 
    
         
             
                    end
         
     | 
| 
       23 
23 
     | 
    
         
             
                  end
         
     | 
| 
       24 
24 
     | 
    
         
             
                end
         
     | 
| 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # @api private
         
     | 
| 
       4 
4 
     | 
    
         
             
            # @since 1.0.0
         
     | 
| 
       5 
     | 
    
         
            -
            module RedisQueuedLocks:: 
     | 
| 
      
 5 
     | 
    
         
            +
            module RedisQueuedLocks::Acquirer::LockInfo
         
     | 
| 
       6 
6 
     | 
    
         
             
              class << self
         
     | 
| 
       7 
7 
     | 
    
         
             
                # @param redis_client [RedisClient]
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @param lock_name [String]
         
     | 
| 
         @@ -10,7 +10,7 @@ module RedisQueuedLocks::Acquier::LockInfo 
     | 
|
| 
       10 
10 
     | 
    
         
             
                #   - `nil` is returned when lock key does not exist or expired;
         
     | 
| 
       11 
11 
     | 
    
         
             
                #   - result format: {
         
     | 
| 
       12 
12 
     | 
    
         
             
                #     'lock_key' => "rql:lock:your_lockname", # acquired lock key
         
     | 
| 
       13 
     | 
    
         
            -
                #     'acq_id' => "rql:acq:123/456/789/987/uniqstring", # lock  
     | 
| 
      
 13 
     | 
    
         
            +
                #     'acq_id' => "rql:acq:123/456/789/987/uniqstring", # lock acquirer identifier
         
     | 
| 
       14 
14 
     | 
    
         
             
                #     'hst_id' => "rql:hst:123/456/987/uniqstring", # lock host identifier
         
     | 
| 
       15 
15 
     | 
    
         
             
                #     'ts' => 123456789.2649841, # <locked at> time stamp (epoch, seconds.microseconds)
         
     | 
| 
       16 
16 
     | 
    
         
             
                #     'ini_ttl' => 123456789, # initial lock key ttl (milliseconds)
         
     | 
| 
         @@ -43,15 +43,19 @@ module RedisQueuedLocks::Acquier::LockInfo 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    #     - lock is expired + re-obtained;
         
     | 
| 
       44 
44 
     | 
    
         
             
                    nil
         
     | 
| 
       45 
45 
     | 
    
         
             
                  else
         
     | 
| 
      
 46 
     | 
    
         
            +
                    # NOTE: the result of MULTI-command is an array of results of each internal command
         
     | 
| 
      
 47 
     | 
    
         
            +
                    #   - result[0] (HGETALL) (Hash<String,String>)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    #     => (will be mutated further with different value types)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    #   - result[1] (PTTL) (Integer)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    #     => (without any mutation, integer is atomic)
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    # @type var result: [Hash[String,String|Float|Integer],Integer]
         
     | 
| 
       46 
53 
     | 
    
         
             
                    hget_cmd_res = result[0]
         
     | 
| 
       47 
54 
     | 
    
         
             
                    pttl_cmd_res = result[1]
         
     | 
| 
       48 
55 
     | 
    
         | 
| 
       49 
56 
     | 
    
         
             
                    if hget_cmd_res == {} || pttl_cmd_res == -2 # NOTE: key does not exist
         
     | 
| 
       50 
57 
     | 
    
         
             
                      nil
         
     | 
| 
       51 
58 
     | 
    
         
             
                    else
         
     | 
| 
       52 
     | 
    
         
            -
                      # NOTE: the result of MULTI-command is an array of results of each internal command
         
     | 
| 
       53 
     | 
    
         
            -
                      #   - result[0] (HGETALL) (Hash<String,String>)
         
     | 
| 
       54 
     | 
    
         
            -
                      #   - result[1] (PTTL) (Integer)
         
     | 
| 
       55 
59 
     | 
    
         
             
                      hget_cmd_res.tap do |lock_data|
         
     | 
| 
       56 
60 
     | 
    
         
             
                        lock_data['lock_key'] = lock_key
         
     | 
| 
       57 
61 
     | 
    
         
             
                        lock_data['ts'] = Float(lock_data['ts'])
         
     |