redlock 1.3.2 → 2.0.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/.github/workflows/ci.yml +2 -2
- data/.gitignore +1 -0
- data/Makefile +0 -3
- data/README.md +5 -5
- data/lib/redlock/client.rb +11 -9
- data/lib/redlock/testing.rb +1 -1
- data/lib/redlock/version.rb +1 -1
- data/redlock.gemspec +1 -1
- data/spec/client_spec.rb +17 -15
- metadata +12 -19
- data/Gemfile.lock +0 -62
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 679d1c44fcda7a2eaa70bdfe38c30e4ee79e417bef0b3ce064aceaf0a9cc0bbb
         | 
| 4 | 
            +
              data.tar.gz: 48b6a41c4cc27b8ff8878647dd494a6b87e3b17e540b75d8699e32d4ee982aa5
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a31815a7da2fa6f5c3af35734294cdb34fdfba19dc12eaf25abe950db65be1356afc397ff29a73823d267d99d0069f86651385c1e262da6ced7541345212abda
         | 
| 7 | 
            +
              data.tar.gz: cd4e41fe60732180b4b5f3d848715954074f8a063c1513c89e73a37311d5d4c0d8fbe1bbd92b063955324929f07bf59232040de104bfeb14d18837d297910d59
         | 
    
        data/.github/workflows/ci.yml
    CHANGED
    
    
    
        data/.gitignore
    CHANGED
    
    
    
        data/Makefile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -15,7 +15,7 @@ This is an implementation of a proposed [distributed lock algorithm with Redis]( | |
| 15 15 |  | 
| 16 16 | 
             
            ## Compatibility
         | 
| 17 17 |  | 
| 18 | 
            -
            Redlock works with Redis versions  | 
| 18 | 
            +
            Redlock works with Redis versions 6.0 or later.
         | 
| 19 19 |  | 
| 20 20 | 
             
            ## Installation
         | 
| 21 21 |  | 
| @@ -151,7 +151,7 @@ lock_manager.get_remaining_ttl_for_lock(lock_info) | |
| 151 151 |  | 
| 152 152 | 
             
            lock_manager.unlock(lock_info)
         | 
| 153 153 | 
             
            lock_manager.get_remaining_ttl_for_lock(lock_info)
         | 
| 154 | 
            -
            #=> nil | 
| 154 | 
            +
            #=> nil
         | 
| 155 155 | 
             
            ```
         | 
| 156 156 |  | 
| 157 157 | 
             
            Use `get_remaining_ttl_for_resource` if you do not hold a lock, but want to know the remaining TTL on a locked resource:
         | 
| @@ -164,13 +164,13 @@ lock_info = lock_manager.lock(resource, 2000) | |
| 164 164 | 
             
            lock_manager.locked?(resource)
         | 
| 165 165 | 
             
            #=> true
         | 
| 166 166 | 
             
            lock_manager.get_remaining_ttl_for_resource(resource)
         | 
| 167 | 
            -
            #=> 1975 | 
| 167 | 
            +
            #=> 1975
         | 
| 168 168 |  | 
| 169 169 | 
             
            # Sometime later
         | 
| 170 170 | 
             
            lock_manager.locked?(resource)
         | 
| 171 171 | 
             
            #=> false
         | 
| 172 172 | 
             
            lock_manager.get_remaining_ttl_for_resource(resource)
         | 
| 173 | 
            -
            #=> nil | 
| 173 | 
            +
            #=> nil
         | 
| 174 174 | 
             
            ```
         | 
| 175 175 |  | 
| 176 176 | 
             
            ## Redis client configuration
         | 
| @@ -178,7 +178,7 @@ lock_manager.get_remaining_ttl_for_resource(resource) | |
| 178 178 | 
             
            `Redlock::Client` expects URLs or Redis objects on initialization. Redis objects should be used for configuring the connection in more detail, i.e. setting username and password.
         | 
| 179 179 |  | 
| 180 180 | 
             
            ```ruby
         | 
| 181 | 
            -
            servers = [ 'redis://localhost:6379',  | 
| 181 | 
            +
            servers = [ 'redis://localhost:6379', RedisClient.new(:url => 'redis://someotherhost:6379') ]
         | 
| 182 182 | 
             
            redlock = Redlock::Client.new(servers)
         | 
| 183 183 | 
             
            ```
         | 
| 184 184 |  | 
    
        data/lib/redlock/client.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require 'redis'
         | 
| 1 | 
            +
            require 'redis-client'
         | 
| 2 2 | 
             
            require 'securerandom'
         | 
| 3 3 |  | 
| 4 4 | 
             
            module Redlock
         | 
| @@ -160,7 +160,7 @@ module Redlock | |
| 160 160 | 
             
                      if connection.respond_to?(:client)
         | 
| 161 161 | 
             
                        @redis = connection
         | 
| 162 162 | 
             
                      else
         | 
| 163 | 
            -
                        @redis =  | 
| 163 | 
            +
                        @redis = RedisClient.new(connection)
         | 
| 164 164 | 
             
                      end
         | 
| 165 165 | 
             
                      @redis.extend(ConnectionPoolLike)
         | 
| 166 166 | 
             
                    end
         | 
| @@ -168,13 +168,13 @@ module Redlock | |
| 168 168 |  | 
| 169 169 | 
             
                  def lock(resource, val, ttl, allow_new_lock)
         | 
| 170 170 | 
             
                    recover_from_script_flush do
         | 
| 171 | 
            -
                      @redis. | 
| 171 | 
            +
                      @redis.call('EVALSHA', Scripts::LOCK_SCRIPT_SHA, 1, resource, val, ttl, allow_new_lock)
         | 
| 172 172 | 
             
                    end
         | 
| 173 173 | 
             
                  end
         | 
| 174 174 |  | 
| 175 175 | 
             
                  def unlock(resource, val)
         | 
| 176 176 | 
             
                    recover_from_script_flush do
         | 
| 177 | 
            -
                      @redis. | 
| 177 | 
            +
                      @redis.call('EVALSHA', Scripts::UNLOCK_SCRIPT_SHA, 1, resource, val)
         | 
| 178 178 | 
             
                    end
         | 
| 179 179 | 
             
                  rescue
         | 
| 180 180 | 
             
                    # Nothing to do, unlocking is just a best-effort attempt.
         | 
| @@ -182,9 +182,9 @@ module Redlock | |
| 182 182 |  | 
| 183 183 | 
             
                  def get_remaining_ttl(resource)
         | 
| 184 184 | 
             
                    recover_from_script_flush do
         | 
| 185 | 
            -
                      @redis. | 
| 185 | 
            +
                      @redis.call('EVALSHA', Scripts::PTTL_SCRIPT_SHA, 1, resource)
         | 
| 186 186 | 
             
                    end
         | 
| 187 | 
            -
                  rescue  | 
| 187 | 
            +
                  rescue RedisClient::ConnectionError
         | 
| 188 188 | 
             
                    nil
         | 
| 189 189 | 
             
                  end
         | 
| 190 190 |  | 
| @@ -197,8 +197,10 @@ module Redlock | |
| 197 197 | 
             
                      Scripts::PTTL_SCRIPT
         | 
| 198 198 | 
             
                    ]
         | 
| 199 199 |  | 
| 200 | 
            -
                     | 
| 201 | 
            -
                       | 
| 200 | 
            +
                    @redis.with do |connnection|
         | 
| 201 | 
            +
                      scripts.each do |script|
         | 
| 202 | 
            +
                        connnection.call('SCRIPT', 'LOAD', script)
         | 
| 203 | 
            +
                      end
         | 
| 202 204 | 
             
                    end
         | 
| 203 205 | 
             
                  end
         | 
| 204 206 |  | 
| @@ -206,7 +208,7 @@ module Redlock | |
| 206 208 | 
             
                    retry_on_noscript = true
         | 
| 207 209 | 
             
                    begin
         | 
| 208 210 | 
             
                      yield
         | 
| 209 | 
            -
                    rescue  | 
| 211 | 
            +
                    rescue RedisClient::CommandError => e
         | 
| 210 212 | 
             
                      # When somebody has flushed the Redis instance's script cache, we might
         | 
| 211 213 | 
             
                      # want to reload our scripts. Only attempt this once, though, to avoid
         | 
| 212 214 | 
             
                      # going into an infinite loop.
         | 
    
        data/lib/redlock/testing.rb
    CHANGED
    
    | @@ -41,7 +41,7 @@ module Redlock | |
| 41 41 |  | 
| 42 42 | 
             
                  def load_scripts
         | 
| 43 43 | 
             
                    load_scripts_without_testing unless Redlock::Client.testing_mode == :bypass
         | 
| 44 | 
            -
                  rescue  | 
| 44 | 
            +
                  rescue RedisClient::CommandError
         | 
| 45 45 | 
             
                    # FakeRedis doesn't have #script, but doesn't need it either.
         | 
| 46 46 | 
             
                    raise unless defined?(::FakeRedis)
         | 
| 47 47 | 
             
                  rescue NoMethodError
         | 
    
        data/lib/redlock/version.rb
    CHANGED
    
    
    
        data/redlock.gemspec
    CHANGED
    
    | @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| | |
| 18 18 | 
             
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 19 19 | 
             
              spec.require_paths = ['lib']
         | 
| 20 20 |  | 
| 21 | 
            -
              spec.add_dependency 'redis' | 
| 21 | 
            +
              spec.add_dependency 'redis-client'
         | 
| 22 22 |  | 
| 23 23 | 
             
              spec.add_development_dependency 'connection_pool', '~> 2.2'
         | 
| 24 24 | 
             
              spec.add_development_dependency 'coveralls', '~> 0.8'
         | 
    
        data/spec/client_spec.rb
    CHANGED
    
    | @@ -1,13 +1,12 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 | 
             
            require 'securerandom'
         | 
| 3 | 
            -
            require 'redis'
         | 
| 4 3 | 
             
            require 'connection_pool'
         | 
| 5 4 |  | 
| 6 5 | 
             
            RSpec.describe Redlock::Client do
         | 
| 7 6 | 
             
              # It is recommended to have at least 3 servers in production
         | 
| 8 7 | 
             
              let(:lock_manager_opts) { { retry_count: 3 } }
         | 
| 9 8 | 
             
              let(:lock_manager) { Redlock::Client.new(Redlock::Client::DEFAULT_REDIS_URLS, lock_manager_opts) }
         | 
| 10 | 
            -
              let(:redis_client) {  | 
| 9 | 
            +
              let(:redis_client) { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
         | 
| 11 10 | 
             
              let(:resource_key) { SecureRandom.hex(3)  }
         | 
| 12 11 | 
             
              let(:ttl) { 1000 }
         | 
| 13 12 | 
             
              let(:redis1_host) { ENV["REDIS1_HOST"] || "localhost" }
         | 
| @@ -17,7 +16,7 @@ RSpec.describe Redlock::Client do | |
| 17 16 | 
             
              let(:redis3_host) { ENV["REDIS3_HOST"] || "127.0.0.1" }
         | 
| 18 17 | 
             
              let(:redis3_port) { ENV["REDIS3_PORT"] || "6379" }
         | 
| 19 18 | 
             
              let(:unreachable_redis) {
         | 
| 20 | 
            -
                redis =  | 
| 19 | 
            +
                redis = RedisClient.new(url: 'redis://localhost:46864')
         | 
| 21 20 | 
             
                def redis.with
         | 
| 22 21 | 
             
                  yield self
         | 
| 23 22 | 
             
                end
         | 
| @@ -26,18 +25,18 @@ RSpec.describe Redlock::Client do | |
| 26 25 |  | 
| 27 26 | 
             
              describe 'initialize' do
         | 
| 28 27 | 
             
                it 'accepts both redis URLs and Redis objects' do
         | 
| 29 | 
            -
                  servers = [ "redis://#{redis1_host}:#{redis1_port}",  | 
| 28 | 
            +
                  servers = [ "redis://#{redis1_host}:#{redis1_port}", RedisClient.new(url: "redis://#{redis2_host}:#{redis2_port}") ]
         | 
| 30 29 | 
             
                  redlock = Redlock::Client.new(servers)
         | 
| 31 30 |  | 
| 32 31 | 
             
                  redlock_servers = redlock.instance_variable_get(:@servers).map do |s|
         | 
| 33 | 
            -
                    s.instance_variable_get(:@redis). | 
| 32 | 
            +
                    s.instance_variable_get(:@redis).config.host
         | 
| 34 33 | 
             
                  end
         | 
| 35 34 |  | 
| 36 35 | 
             
                  expect(redlock_servers).to match_array([redis1_host, redis2_host])
         | 
| 37 36 | 
             
                end
         | 
| 38 37 |  | 
| 39 38 | 
             
                it 'accepts ConnectionPool objects' do
         | 
| 40 | 
            -
                  pool = ConnectionPool.new {  | 
| 39 | 
            +
                  pool = ConnectionPool.new { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
         | 
| 41 40 | 
             
                  redlock = Redlock::Client.new([pool])
         | 
| 42 41 |  | 
| 43 42 | 
             
                  lock_info = lock_manager.lock(resource_key, ttl)
         | 
| @@ -46,12 +45,15 @@ RSpec.describe Redlock::Client do | |
| 46 45 | 
             
                end
         | 
| 47 46 |  | 
| 48 47 | 
             
                it 'does not load scripts' do
         | 
| 49 | 
            -
                  redis_client. | 
| 48 | 
            +
                  redis_client.call('SCRIPT', 'FLUSH')
         | 
| 50 49 |  | 
| 51 | 
            -
                  pool = ConnectionPool.new {  | 
| 50 | 
            +
                  pool = ConnectionPool.new { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
         | 
| 52 51 | 
             
                  redlock = Redlock::Client.new([pool])
         | 
| 53 52 |  | 
| 54 | 
            -
                   | 
| 53 | 
            +
                  raw_info = redis_client.call('INFO')
         | 
| 54 | 
            +
                  number_of_cached_scripts = raw_info[/number_of_cached_scripts\:\d+/].split(':').last
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  expect(number_of_cached_scripts).to eq("0")
         | 
| 55 57 | 
             
                end
         | 
| 56 58 | 
             
              end
         | 
| 57 59 |  | 
| @@ -74,7 +76,7 @@ RSpec.describe Redlock::Client do | |
| 74 76 | 
             
                  it 'interprets lock time as milliseconds' do
         | 
| 75 77 | 
             
                    ttl = 20000
         | 
| 76 78 | 
             
                    @lock_info = lock_manager.lock(resource_key, ttl)
         | 
| 77 | 
            -
                    expect(redis_client. | 
| 79 | 
            +
                    expect(redis_client.call('PTTL', resource_key)).to be_within(200).of(ttl)
         | 
| 78 80 | 
             
                  end
         | 
| 79 81 |  | 
| 80 82 | 
             
                  it 'can extend its own lock' do
         | 
| @@ -106,7 +108,7 @@ RSpec.describe Redlock::Client do | |
| 106 108 |  | 
| 107 109 | 
             
                    lock_info = lock_manager.lock(resource_key, ttl, extend: lock_info, extend_only_if_locked: true)
         | 
| 108 110 | 
             
                    expect(lock_info).not_to be_nil
         | 
| 109 | 
            -
                    expect(redis_client. | 
| 111 | 
            +
                    expect(redis_client.call('PTTL', resource_key)).to be_within(200).of(ttl)
         | 
| 110 112 | 
             
                  end
         | 
| 111 113 |  | 
| 112 114 | 
             
                  context 'when extend_only_if_locked flag is not given' do
         | 
| @@ -249,7 +251,7 @@ RSpec.describe Redlock::Client do | |
| 249 251 |  | 
| 250 252 | 
             
                    expect {
         | 
| 251 253 | 
             
                      lock_manager.lock(resource_key, ttl)
         | 
| 252 | 
            -
                    }.to raise_error( | 
| 254 | 
            +
                    }.to raise_error(RedisClient::CannotConnectError)
         | 
| 253 255 | 
             
                  end
         | 
| 254 256 | 
             
                end
         | 
| 255 257 |  | 
| @@ -261,7 +263,7 @@ RSpec.describe Redlock::Client do | |
| 261 263 | 
             
                    redis_instance.instance_variable_set(:@redis, unreachable_redis)
         | 
| 262 264 | 
             
                    expect {
         | 
| 263 265 | 
             
                      lock_manager.lock(resource_key, ttl)
         | 
| 264 | 
            -
                    }.to raise_error( | 
| 266 | 
            +
                    }.to raise_error(RedisClient::CannotConnectError)
         | 
| 265 267 | 
             
                    redis_instance.instance_variable_set(:@redis, old_redis)
         | 
| 266 268 | 
             
                    expect(lock_manager.lock(resource_key, ttl)).to be_truthy
         | 
| 267 269 | 
             
                  end
         | 
| @@ -270,10 +272,10 @@ RSpec.describe Redlock::Client do | |
| 270 272 | 
             
                context 'when script cache has been flushed' do
         | 
| 271 273 | 
             
                  before(:each) do
         | 
| 272 274 | 
             
                    @manipulated_instance = lock_manager.instance_variable_get(:@servers).first
         | 
| 273 | 
            -
                    @manipulated_instance.instance_variable_get(:@redis). | 
| 275 | 
            +
                    @manipulated_instance.instance_variable_get(:@redis).call('SCRIPT', 'FLUSH')
         | 
| 274 276 | 
             
                  end
         | 
| 275 277 |  | 
| 276 | 
            -
                  it 'does not raise a  | 
| 278 | 
            +
                  it 'does not raise a RedisClient::CommandError: NOSCRIPT error' do
         | 
| 277 279 | 
             
                    expect {
         | 
| 278 280 | 
             
                      lock_manager.lock(resource_key, ttl)
         | 
| 279 281 | 
             
                    }.to_not raise_error
         | 
    
        metadata
    CHANGED
    
    | @@ -1,35 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: redlock
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 2.0.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Leandro Moreira
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2023-02-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            -
              name: redis
         | 
| 14 | 
            +
              name: redis-client
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 20 | 
            -
                - - "<"
         | 
| 21 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 22 | 
            -
                    version: '6.0'
         | 
| 19 | 
            +
                    version: '0'
         | 
| 23 20 | 
             
              type: :runtime
         | 
| 24 21 | 
             
              prerelease: false
         | 
| 25 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 26 23 | 
             
                requirements:
         | 
| 27 24 | 
             
                - - ">="
         | 
| 28 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            -
                    version:  | 
| 30 | 
            -
                - - "<"
         | 
| 31 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            -
                    version: '6.0'
         | 
| 26 | 
            +
                    version: '0'
         | 
| 33 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 34 28 | 
             
              name: connection_pool
         | 
| 35 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -102,22 +96,22 @@ dependencies: | |
| 102 96 | 
             
              name: rspec
         | 
| 103 97 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 104 98 | 
             
                requirements:
         | 
| 105 | 
            -
                - - "~>"
         | 
| 106 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 107 | 
            -
                    version: '3'
         | 
| 108 99 | 
             
                - - ">="
         | 
| 109 100 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 101 | 
             
                    version: 3.0.0
         | 
| 102 | 
            +
                - - "~>"
         | 
| 103 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 104 | 
            +
                    version: '3'
         | 
| 111 105 | 
             
              type: :development
         | 
| 112 106 | 
             
              prerelease: false
         | 
| 113 107 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 114 108 | 
             
                requirements:
         | 
| 115 | 
            -
                - - "~>"
         | 
| 116 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            -
                    version: '3'
         | 
| 118 109 | 
             
                - - ">="
         | 
| 119 110 | 
             
                  - !ruby/object:Gem::Version
         | 
| 120 111 | 
             
                    version: 3.0.0
         | 
| 112 | 
            +
                - - "~>"
         | 
| 113 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 114 | 
            +
                    version: '3'
         | 
| 121 115 | 
             
            description: Distributed lock using Redis written in Ruby. Highly inspired by https://github.com/antirez/redlock-rb.
         | 
| 122 116 | 
             
            email:
         | 
| 123 117 | 
             
            - leandro.ribeiro.moreira@gmail.com
         | 
| @@ -130,7 +124,6 @@ files: | |
| 130 124 | 
             
            - ".rspec"
         | 
| 131 125 | 
             
            - CONTRIBUTORS
         | 
| 132 126 | 
             
            - Gemfile
         | 
| 133 | 
            -
            - Gemfile.lock
         | 
| 134 127 | 
             
            - LICENSE
         | 
| 135 128 | 
             
            - Makefile
         | 
| 136 129 | 
             
            - README.md
         | 
| @@ -165,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 165 158 | 
             
                - !ruby/object:Gem::Version
         | 
| 166 159 | 
             
                  version: '0'
         | 
| 167 160 | 
             
            requirements: []
         | 
| 168 | 
            -
            rubygems_version: 3.3. | 
| 161 | 
            +
            rubygems_version: 3.0.3.1
         | 
| 169 162 | 
             
            signing_key: 
         | 
| 170 163 | 
             
            specification_version: 4
         | 
| 171 164 | 
             
            summary: Distributed lock using Redis written in Ruby.
         | 
    
        data/Gemfile.lock
    DELETED
    
    | @@ -1,62 +0,0 @@ | |
| 1 | 
            -
            PATH
         | 
| 2 | 
            -
              remote: .
         | 
| 3 | 
            -
              specs:
         | 
| 4 | 
            -
                redlock (1.3.2)
         | 
| 5 | 
            -
                  redis (>= 3.0.0, < 6.0)
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            GEM
         | 
| 8 | 
            -
              remote: https://rubygems.org/
         | 
| 9 | 
            -
              specs:
         | 
| 10 | 
            -
                connection_pool (2.3.0)
         | 
| 11 | 
            -
                coveralls (0.8.23)
         | 
| 12 | 
            -
                  json (>= 1.8, < 3)
         | 
| 13 | 
            -
                  simplecov (~> 0.16.1)
         | 
| 14 | 
            -
                  term-ansicolor (~> 1.3)
         | 
| 15 | 
            -
                  thor (>= 0.19.4, < 2.0)
         | 
| 16 | 
            -
                  tins (~> 1.6)
         | 
| 17 | 
            -
                diff-lcs (1.5.0)
         | 
| 18 | 
            -
                docile (1.4.0)
         | 
| 19 | 
            -
                json (2.3.1)
         | 
| 20 | 
            -
                rake (13.0.6)
         | 
| 21 | 
            -
                redis (5.0.5)
         | 
| 22 | 
            -
                  redis-client (>= 0.9.0)
         | 
| 23 | 
            -
                redis-client (0.10.0)
         | 
| 24 | 
            -
                  connection_pool
         | 
| 25 | 
            -
                rspec (3.11.0)
         | 
| 26 | 
            -
                  rspec-core (~> 3.11.0)
         | 
| 27 | 
            -
                  rspec-expectations (~> 3.11.0)
         | 
| 28 | 
            -
                  rspec-mocks (~> 3.11.0)
         | 
| 29 | 
            -
                rspec-core (3.11.0)
         | 
| 30 | 
            -
                  rspec-support (~> 3.11.0)
         | 
| 31 | 
            -
                rspec-expectations (3.11.1)
         | 
| 32 | 
            -
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 33 | 
            -
                  rspec-support (~> 3.11.0)
         | 
| 34 | 
            -
                rspec-mocks (3.11.1)
         | 
| 35 | 
            -
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 36 | 
            -
                  rspec-support (~> 3.11.0)
         | 
| 37 | 
            -
                rspec-support (3.11.1)
         | 
| 38 | 
            -
                simplecov (0.16.1)
         | 
| 39 | 
            -
                  docile (~> 1.1)
         | 
| 40 | 
            -
                  json (>= 1.8, < 3)
         | 
| 41 | 
            -
                  simplecov-html (~> 0.10.0)
         | 
| 42 | 
            -
                simplecov-html (0.10.2)
         | 
| 43 | 
            -
                sync (0.5.0)
         | 
| 44 | 
            -
                term-ansicolor (1.7.1)
         | 
| 45 | 
            -
                  tins (~> 1.0)
         | 
| 46 | 
            -
                thor (1.2.1)
         | 
| 47 | 
            -
                tins (1.31.1)
         | 
| 48 | 
            -
                  sync
         | 
| 49 | 
            -
             | 
| 50 | 
            -
            PLATFORMS
         | 
| 51 | 
            -
              ruby
         | 
| 52 | 
            -
             | 
| 53 | 
            -
            DEPENDENCIES
         | 
| 54 | 
            -
              connection_pool (~> 2.2)
         | 
| 55 | 
            -
              coveralls (~> 0.8)
         | 
| 56 | 
            -
              json (~> 2.3.1, >= 2.3.0)
         | 
| 57 | 
            -
              rake (~> 13.0, >= 11.1.2)
         | 
| 58 | 
            -
              redlock!
         | 
| 59 | 
            -
              rspec (~> 3, >= 3.0.0)
         | 
| 60 | 
            -
             | 
| 61 | 
            -
            BUNDLED WITH
         | 
| 62 | 
            -
               2.3.7
         |