redis 4.8.0 → 5.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +64 -1
 - data/README.md +101 -161
 - data/lib/redis/client.rb +82 -625
 - data/lib/redis/commands/bitmaps.rb +4 -1
 - data/lib/redis/commands/cluster.rb +1 -18
 - data/lib/redis/commands/connection.rb +5 -10
 - data/lib/redis/commands/geo.rb +3 -3
 - data/lib/redis/commands/hashes.rb +9 -6
 - data/lib/redis/commands/hyper_log_log.rb +1 -1
 - data/lib/redis/commands/keys.rb +5 -23
 - data/lib/redis/commands/lists.rb +74 -25
 - data/lib/redis/commands/pubsub.rb +28 -25
 - data/lib/redis/commands/server.rb +15 -15
 - data/lib/redis/commands/sets.rb +31 -40
 - data/lib/redis/commands/sorted_sets.rb +84 -12
 - data/lib/redis/commands/streams.rb +39 -19
 - data/lib/redis/commands/strings.rb +18 -17
 - data/lib/redis/commands/transactions.rb +7 -31
 - data/lib/redis/commands.rb +4 -7
 - data/lib/redis/distributed.rb +114 -64
 - data/lib/redis/errors.rb +15 -50
 - data/lib/redis/hash_ring.rb +26 -26
 - data/lib/redis/pipeline.rb +43 -222
 - data/lib/redis/subscribe.rb +50 -14
 - data/lib/redis/version.rb +1 -1
 - data/lib/redis.rb +76 -184
 - metadata +10 -54
 - data/lib/redis/cluster/command.rb +0 -79
 - data/lib/redis/cluster/command_loader.rb +0 -33
 - data/lib/redis/cluster/key_slot_converter.rb +0 -72
 - data/lib/redis/cluster/node.rb +0 -120
 - data/lib/redis/cluster/node_key.rb +0 -31
 - data/lib/redis/cluster/node_loader.rb +0 -34
 - data/lib/redis/cluster/option.rb +0 -100
 - data/lib/redis/cluster/slot.rb +0 -86
 - data/lib/redis/cluster/slot_loader.rb +0 -46
 - data/lib/redis/cluster.rb +0 -315
 - data/lib/redis/connection/command_helper.rb +0 -41
 - data/lib/redis/connection/hiredis.rb +0 -68
 - data/lib/redis/connection/registry.rb +0 -13
 - data/lib/redis/connection/ruby.rb +0 -437
 - data/lib/redis/connection/synchrony.rb +0 -148
 - data/lib/redis/connection.rb +0 -11
 
    
        data/lib/redis.rb
    CHANGED
    
    | 
         @@ -6,26 +6,10 @@ require "redis/commands" 
     | 
|
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            class Redis
         
     | 
| 
       8 
8 
     | 
    
         
             
              BASE_PATH = __dir__
         
     | 
| 
       9 
     | 
    
         
            -
              @exists_returns_integer = true
         
     | 
| 
       10 
     | 
    
         
            -
              @sadd_returns_boolean = true
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
9 
     | 
    
         
             
              Deprecated = Class.new(StandardError)
         
     | 
| 
       13 
10 
     | 
    
         | 
| 
       14 
11 
     | 
    
         
             
              class << self
         
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
       16 
     | 
    
         
            -
                attr_accessor :silence_deprecations, :raise_deprecations, :sadd_returns_boolean
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                def exists_returns_integer=(value)
         
     | 
| 
       19 
     | 
    
         
            -
                  unless value
         
     | 
| 
       20 
     | 
    
         
            -
                    deprecate!(
         
     | 
| 
       21 
     | 
    
         
            -
                      "`Redis#exists(key)` will return an Integer by default in redis-rb 4.3. The option to explicitly " \
         
     | 
| 
       22 
     | 
    
         
            -
                      "disable this behaviour via `Redis.exists_returns_integer` will be removed in 5.0. You should use " \
         
     | 
| 
       23 
     | 
    
         
            -
                      "`exists?` instead."
         
     | 
| 
       24 
     | 
    
         
            -
                    )
         
     | 
| 
       25 
     | 
    
         
            -
                  end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                  @exists_returns_integer = value
         
     | 
| 
       28 
     | 
    
         
            -
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor :silence_deprecations, :raise_deprecations
         
     | 
| 
       29 
13 
     | 
    
         | 
| 
       30 
14 
     | 
    
         
             
                def deprecate!(message)
         
     | 
| 
       31 
15 
     | 
    
         
             
                  unless silence_deprecations
         
     | 
| 
         @@ -36,20 +20,22 @@ class Redis 
     | 
|
| 
       36 
20 
     | 
    
         
             
                    end
         
     | 
| 
       37 
21 
     | 
    
         
             
                  end
         
     | 
| 
       38 
22 
     | 
    
         
             
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
       39 
24 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                 
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
       47 
     | 
    
         
            -
                  @current = redis
         
     | 
| 
      
 25 
     | 
    
         
            +
              # soft-deprecated
         
     | 
| 
      
 26 
     | 
    
         
            +
              # We added this back for older sidekiq releases
         
     | 
| 
      
 27 
     | 
    
         
            +
              module Connection
         
     | 
| 
      
 28 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def drivers
         
     | 
| 
      
 30 
     | 
    
         
            +
                    [RedisClient.default_driver]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
       48 
32 
     | 
    
         
             
                end
         
     | 
| 
       49 
33 
     | 
    
         
             
              end
         
     | 
| 
       50 
34 
     | 
    
         | 
| 
       51 
35 
     | 
    
         
             
              include Commands
         
     | 
| 
       52 
36 
     | 
    
         | 
| 
      
 37 
     | 
    
         
            +
              SERVER_URL_OPTIONS = %i(url host port path).freeze
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       53 
39 
     | 
    
         
             
              # Create a new client instance
         
     | 
| 
       54 
40 
     | 
    
         
             
              #
         
     | 
| 
       55 
41 
     | 
    
         
             
              # @param [Hash] options
         
     | 
| 
         @@ -59,56 +45,49 @@ class Redis 
     | 
|
| 
       59 
45 
     | 
    
         
             
              # @option options [String] :host ("127.0.0.1") server hostname
         
     | 
| 
       60 
46 
     | 
    
         
             
              # @option options [Integer] :port (6379) server port
         
     | 
| 
       61 
47 
     | 
    
         
             
              # @option options [String] :path path to server socket (overrides host and port)
         
     | 
| 
       62 
     | 
    
         
            -
              # @option options [Float] :timeout ( 
     | 
| 
      
 48 
     | 
    
         
            +
              # @option options [Float] :timeout (1.0) timeout in seconds
         
     | 
| 
       63 
49 
     | 
    
         
             
              # @option options [Float] :connect_timeout (same as timeout) timeout for initial connect in seconds
         
     | 
| 
       64 
50 
     | 
    
         
             
              # @option options [String] :username Username to authenticate against server
         
     | 
| 
       65 
51 
     | 
    
         
             
              # @option options [String] :password Password to authenticate against server
         
     | 
| 
       66 
     | 
    
         
            -
              # @option options [Integer] :db (0) Database to select after  
     | 
| 
       67 
     | 
    
         
            -
              # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis 
     | 
| 
      
 52 
     | 
    
         
            +
              # @option options [Integer] :db (0) Database to select after connect and on reconnects
         
     | 
| 
      
 53 
     | 
    
         
            +
              # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`
         
     | 
| 
       68 
54 
     | 
    
         
             
              # @option options [String] :id ID for the client connection, assigns name to current connection by sending
         
     | 
| 
       69 
55 
     | 
    
         
             
              #   `CLIENT SETNAME`
         
     | 
| 
       70 
     | 
    
         
            -
              # @option options [ 
     | 
| 
       71 
     | 
    
         
            -
              #    
     | 
| 
       72 
     | 
    
         
            -
              # @option options [Integer] :reconnect_attempts Number of attempts trying to connect
         
     | 
| 
      
 56 
     | 
    
         
            +
              # @option options [Integer, Array<Integer, Float>] :reconnect_attempts Number of attempts trying to connect,
         
     | 
| 
      
 57 
     | 
    
         
            +
              #   or a list of sleep duration between attempts.
         
     | 
| 
       73 
58 
     | 
    
         
             
              # @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not
         
     | 
| 
      
 59 
     | 
    
         
            +
              # @option options [String] :name The name of the server group to connect to.
         
     | 
| 
       74 
60 
     | 
    
         
             
              # @option options [Array] :sentinels List of sentinels to contact
         
     | 
| 
       75 
     | 
    
         
            -
              # @option options [Symbol] :role (:master) Role to fetch via Sentinel, either `:master` or `:slave`
         
     | 
| 
       76 
     | 
    
         
            -
              # @option options [Array<String, Hash{Symbol => String, Integer}>] :cluster List of cluster nodes to contact
         
     | 
| 
       77 
     | 
    
         
            -
              # @option options [Boolean] :replica Whether to use readonly replica nodes in Redis Cluster or not
         
     | 
| 
       78 
     | 
    
         
            -
              # @option options [String] :fixed_hostname Specify a FQDN if cluster mode enabled and
         
     | 
| 
       79 
     | 
    
         
            -
              #   client has to connect nodes via single endpoint with SSL/TLS
         
     | 
| 
       80 
     | 
    
         
            -
              # @option options [Class] :connector Class of custom connector
         
     | 
| 
       81 
61 
     | 
    
         
             
              #
         
     | 
| 
       82 
62 
     | 
    
         
             
              # @return [Redis] a new client instance
         
     | 
| 
       83 
63 
     | 
    
         
             
              def initialize(options = {})
         
     | 
| 
       84 
     | 
    
         
            -
                @options = options.dup
         
     | 
| 
       85 
     | 
    
         
            -
                @cluster_mode = options.key?(:cluster)
         
     | 
| 
       86 
     | 
    
         
            -
                client = @cluster_mode ? Cluster : Client
         
     | 
| 
       87 
     | 
    
         
            -
                @original_client = @client = client.new(options)
         
     | 
| 
       88 
     | 
    
         
            -
                @queue = Hash.new { |h, k| h[k] = [] }
         
     | 
| 
       89 
64 
     | 
    
         
             
                @monitor = Monitor.new
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                synchronize do |client|
         
     | 
| 
       95 
     | 
    
         
            -
                  client.with_reconnect(val, &blk)
         
     | 
| 
      
 65 
     | 
    
         
            +
                @options = options.dup
         
     | 
| 
      
 66 
     | 
    
         
            +
                @options[:reconnect_attempts] = 1 unless @options.key?(:reconnect_attempts)
         
     | 
| 
      
 67 
     | 
    
         
            +
                if ENV["REDIS_URL"] && SERVER_URL_OPTIONS.none? { |o| @options.key?(o) }
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @options[:url] = ENV["REDIS_URL"]
         
     | 
| 
       96 
69 
     | 
    
         
             
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
                inherit_socket = @options.delete(:inherit_socket)
         
     | 
| 
      
 71 
     | 
    
         
            +
                @subscription_client = nil
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                @client = initialize_client(@options)
         
     | 
| 
      
 74 
     | 
    
         
            +
                @client.inherit_socket! if inherit_socket
         
     | 
| 
       97 
75 
     | 
    
         
             
              end
         
     | 
| 
       98 
76 
     | 
    
         | 
| 
       99 
77 
     | 
    
         
             
              # Run code without the client reconnecting
         
     | 
| 
       100 
     | 
    
         
            -
              def without_reconnect(& 
     | 
| 
       101 
     | 
    
         
            -
                 
     | 
| 
      
 78 
     | 
    
         
            +
              def without_reconnect(&block)
         
     | 
| 
      
 79 
     | 
    
         
            +
                @client.disable_reconnection(&block)
         
     | 
| 
       102 
80 
     | 
    
         
             
              end
         
     | 
| 
       103 
81 
     | 
    
         | 
| 
       104 
82 
     | 
    
         
             
              # Test whether or not the client is connected
         
     | 
| 
       105 
83 
     | 
    
         
             
              def connected?
         
     | 
| 
       106 
     | 
    
         
            -
                @ 
     | 
| 
      
 84 
     | 
    
         
            +
                @client.connected? || @subscription_client&.connected?
         
     | 
| 
       107 
85 
     | 
    
         
             
              end
         
     | 
| 
       108 
86 
     | 
    
         | 
| 
       109 
87 
     | 
    
         
             
              # Disconnect the client as quickly and silently as possible.
         
     | 
| 
       110 
88 
     | 
    
         
             
              def close
         
     | 
| 
       111 
     | 
    
         
            -
                @ 
     | 
| 
      
 89 
     | 
    
         
            +
                @client.close
         
     | 
| 
      
 90 
     | 
    
         
            +
                @subscription_client&.close
         
     | 
| 
       112 
91 
     | 
    
         
             
              end
         
     | 
| 
       113 
92 
     | 
    
         
             
              alias disconnect! close
         
     | 
| 
       114 
93 
     | 
    
         | 
| 
         @@ -116,127 +95,20 @@ class Redis 
     | 
|
| 
       116 
95 
     | 
    
         
             
                yield self
         
     | 
| 
       117 
96 
     | 
    
         
             
              end
         
     | 
| 
       118 
97 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
              # @deprecated Queues a command for pipelining.
         
     | 
| 
       120 
     | 
    
         
            -
              #
         
     | 
| 
       121 
     | 
    
         
            -
              # Commands in the queue are executed with the Redis#commit method.
         
     | 
| 
       122 
     | 
    
         
            -
              #
         
     | 
| 
       123 
     | 
    
         
            -
              # See http://redis.io/topics/pipelining for more details.
         
     | 
| 
       124 
     | 
    
         
            -
              #
         
     | 
| 
       125 
     | 
    
         
            -
              def queue(*command)
         
     | 
| 
       126 
     | 
    
         
            -
                ::Redis.deprecate!(
         
     | 
| 
       127 
     | 
    
         
            -
                  "Redis#queue is deprecated and will be removed in Redis 5.0.0. Use Redis#pipelined instead." \
         
     | 
| 
       128 
     | 
    
         
            -
                  "(called from: #{caller(1, 1).first})"
         
     | 
| 
       129 
     | 
    
         
            -
                )
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                synchronize do
         
     | 
| 
       132 
     | 
    
         
            -
                  @queue[Thread.current.object_id] << command
         
     | 
| 
       133 
     | 
    
         
            -
                end
         
     | 
| 
       134 
     | 
    
         
            -
              end
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
              # @deprecated Sends all commands in the queue.
         
     | 
| 
       137 
     | 
    
         
            -
              #
         
     | 
| 
       138 
     | 
    
         
            -
              # See http://redis.io/topics/pipelining for more details.
         
     | 
| 
       139 
     | 
    
         
            -
              #
         
     | 
| 
       140 
     | 
    
         
            -
              def commit
         
     | 
| 
       141 
     | 
    
         
            -
                ::Redis.deprecate!(
         
     | 
| 
       142 
     | 
    
         
            -
                  "Redis#commit is deprecated and will be removed in Redis 5.0.0. Use Redis#pipelined instead. " \
         
     | 
| 
       143 
     | 
    
         
            -
                  "(called from: #{Kernel.caller(1, 1).first})"
         
     | 
| 
       144 
     | 
    
         
            -
                )
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                synchronize do |client|
         
     | 
| 
       147 
     | 
    
         
            -
                  begin
         
     | 
| 
       148 
     | 
    
         
            -
                    pipeline = Pipeline.new(client)
         
     | 
| 
       149 
     | 
    
         
            -
                    @queue[Thread.current.object_id].each do |command|
         
     | 
| 
       150 
     | 
    
         
            -
                      pipeline.call(command)
         
     | 
| 
       151 
     | 
    
         
            -
                    end
         
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
                    client.call_pipelined(pipeline)
         
     | 
| 
       154 
     | 
    
         
            -
                  ensure
         
     | 
| 
       155 
     | 
    
         
            -
                    @queue.delete(Thread.current.object_id)
         
     | 
| 
       156 
     | 
    
         
            -
                  end
         
     | 
| 
       157 
     | 
    
         
            -
                end
         
     | 
| 
       158 
     | 
    
         
            -
              end
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
98 
     | 
    
         
             
              def _client
         
     | 
| 
       161 
99 
     | 
    
         
             
                @client
         
     | 
| 
       162 
100 
     | 
    
         
             
              end
         
     | 
| 
       163 
101 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
              def pipelined 
     | 
| 
       165 
     | 
    
         
            -
                 
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
                  deprecation_displayed = true
         
     | 
| 
       169 
     | 
    
         
            -
                end
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
                synchronize do |prior_client|
         
     | 
| 
       172 
     | 
    
         
            -
                  begin
         
     | 
| 
       173 
     | 
    
         
            -
                    pipeline = Pipeline.new(prior_client)
         
     | 
| 
       174 
     | 
    
         
            -
                    @client = deprecation_displayed ? pipeline : DeprecatedPipeline.new(pipeline)
         
     | 
| 
       175 
     | 
    
         
            -
                    pipelined_connection = PipelinedConnection.new(pipeline)
         
     | 
| 
       176 
     | 
    
         
            -
                    yield pipelined_connection
         
     | 
| 
       177 
     | 
    
         
            -
                    prior_client.call_pipeline(pipeline)
         
     | 
| 
       178 
     | 
    
         
            -
                  ensure
         
     | 
| 
       179 
     | 
    
         
            -
                    @client = prior_client
         
     | 
| 
       180 
     | 
    
         
            -
                  end
         
     | 
| 
       181 
     | 
    
         
            -
                end
         
     | 
| 
       182 
     | 
    
         
            -
              end
         
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
              # Mark the start of a transaction block.
         
     | 
| 
       185 
     | 
    
         
            -
              #
         
     | 
| 
       186 
     | 
    
         
            -
              # Passing a block is optional.
         
     | 
| 
       187 
     | 
    
         
            -
              #
         
     | 
| 
       188 
     | 
    
         
            -
              # @example With a block
         
     | 
| 
       189 
     | 
    
         
            -
              #   redis.multi do |multi|
         
     | 
| 
       190 
     | 
    
         
            -
              #     multi.set("key", "value")
         
     | 
| 
       191 
     | 
    
         
            -
              #     multi.incr("counter")
         
     | 
| 
       192 
     | 
    
         
            -
              #   end # => ["OK", 6]
         
     | 
| 
       193 
     | 
    
         
            -
              #
         
     | 
| 
       194 
     | 
    
         
            -
              # @example Without a block
         
     | 
| 
       195 
     | 
    
         
            -
              #   redis.multi
         
     | 
| 
       196 
     | 
    
         
            -
              #     # => "OK"
         
     | 
| 
       197 
     | 
    
         
            -
              #   redis.set("key", "value")
         
     | 
| 
       198 
     | 
    
         
            -
              #     # => "QUEUED"
         
     | 
| 
       199 
     | 
    
         
            -
              #   redis.incr("counter")
         
     | 
| 
       200 
     | 
    
         
            -
              #     # => "QUEUED"
         
     | 
| 
       201 
     | 
    
         
            -
              #   redis.exec
         
     | 
| 
       202 
     | 
    
         
            -
              #     # => ["OK", 6]
         
     | 
| 
       203 
     | 
    
         
            -
              #
         
     | 
| 
       204 
     | 
    
         
            -
              # @yield [multi] the commands that are called inside this block are cached
         
     | 
| 
       205 
     | 
    
         
            -
              #   and written to the server upon returning from it
         
     | 
| 
       206 
     | 
    
         
            -
              # @yieldparam [Redis] multi `self`
         
     | 
| 
       207 
     | 
    
         
            -
              #
         
     | 
| 
       208 
     | 
    
         
            -
              # @return [String, Array<...>]
         
     | 
| 
       209 
     | 
    
         
            -
              #   - when a block is not given, `OK`
         
     | 
| 
       210 
     | 
    
         
            -
              #   - when a block is given, an array with replies
         
     | 
| 
       211 
     | 
    
         
            -
              #
         
     | 
| 
       212 
     | 
    
         
            -
              # @see #watch
         
     | 
| 
       213 
     | 
    
         
            -
              # @see #unwatch
         
     | 
| 
       214 
     | 
    
         
            -
              def multi(&block)
         
     | 
| 
       215 
     | 
    
         
            -
                if block_given?
         
     | 
| 
       216 
     | 
    
         
            -
                  deprecation_displayed = false
         
     | 
| 
       217 
     | 
    
         
            -
                  if block&.arity == 0
         
     | 
| 
       218 
     | 
    
         
            -
                    Pipeline.deprecation_warning("multi", Kernel.caller_locations(1, 5))
         
     | 
| 
       219 
     | 
    
         
            -
                    deprecation_displayed = true
         
     | 
| 
       220 
     | 
    
         
            -
                  end
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
                  synchronize do |prior_client|
         
     | 
| 
       223 
     | 
    
         
            -
                    begin
         
     | 
| 
       224 
     | 
    
         
            -
                      pipeline = Pipeline::Multi.new(prior_client)
         
     | 
| 
       225 
     | 
    
         
            -
                      @client = deprecation_displayed ? pipeline : DeprecatedMulti.new(pipeline)
         
     | 
| 
       226 
     | 
    
         
            -
                      pipelined_connection = PipelinedConnection.new(pipeline)
         
     | 
| 
       227 
     | 
    
         
            -
                      yield pipelined_connection
         
     | 
| 
       228 
     | 
    
         
            -
                      prior_client.call_pipeline(pipeline)
         
     | 
| 
       229 
     | 
    
         
            -
                    ensure
         
     | 
| 
       230 
     | 
    
         
            -
                      @client = prior_client
         
     | 
| 
       231 
     | 
    
         
            -
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
              def pipelined
         
     | 
| 
      
 103 
     | 
    
         
            +
                synchronize do |client|
         
     | 
| 
      
 104 
     | 
    
         
            +
                  client.pipelined do |raw_pipeline|
         
     | 
| 
      
 105 
     | 
    
         
            +
                    yield PipelinedConnection.new(raw_pipeline)
         
     | 
| 
       232 
106 
     | 
    
         
             
                  end
         
     | 
| 
       233 
     | 
    
         
            -
                else
         
     | 
| 
       234 
     | 
    
         
            -
                  send_command([:multi])
         
     | 
| 
       235 
107 
     | 
    
         
             
                end
         
     | 
| 
       236 
108 
     | 
    
         
             
              end
         
     | 
| 
       237 
109 
     | 
    
         | 
| 
       238 
110 
     | 
    
         
             
              def id
         
     | 
| 
       239 
     | 
    
         
            -
                @ 
     | 
| 
      
 111 
     | 
    
         
            +
                @client.id || @client.server_url
         
     | 
| 
       240 
112 
     | 
    
         
             
              end
         
     | 
| 
       241 
113 
     | 
    
         | 
| 
       242 
114 
     | 
    
         
             
              def inspect
         
     | 
| 
         @@ -248,54 +120,74 @@ class Redis 
     | 
|
| 
       248 
120 
     | 
    
         
             
              end
         
     | 
| 
       249 
121 
     | 
    
         | 
| 
       250 
122 
     | 
    
         
             
              def connection
         
     | 
| 
       251 
     | 
    
         
            -
                return @original_client.connection_info if @cluster_mode
         
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
123 
     | 
    
         
             
                {
         
     | 
| 
       254 
     | 
    
         
            -
                  host: @ 
     | 
| 
       255 
     | 
    
         
            -
                  port: @ 
     | 
| 
       256 
     | 
    
         
            -
                  db: @ 
     | 
| 
       257 
     | 
    
         
            -
                  id:  
     | 
| 
       258 
     | 
    
         
            -
                  location: @ 
     | 
| 
      
 124 
     | 
    
         
            +
                  host: @client.host,
         
     | 
| 
      
 125 
     | 
    
         
            +
                  port: @client.port,
         
     | 
| 
      
 126 
     | 
    
         
            +
                  db: @client.db,
         
     | 
| 
      
 127 
     | 
    
         
            +
                  id: id,
         
     | 
| 
      
 128 
     | 
    
         
            +
                  location: "#{@client.host}:#{@client.port}"
         
     | 
| 
       259 
129 
     | 
    
         
             
                }
         
     | 
| 
       260 
130 
     | 
    
         
             
              end
         
     | 
| 
       261 
131 
     | 
    
         | 
| 
       262 
132 
     | 
    
         
             
              private
         
     | 
| 
       263 
133 
     | 
    
         | 
| 
      
 134 
     | 
    
         
            +
              def initialize_client(options)
         
     | 
| 
      
 135 
     | 
    
         
            +
                if options.key?(:cluster)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  raise "Redis Cluster support was moved to the `redis-clustering` gem."
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                if options.key?(:sentinels)
         
     | 
| 
      
 140 
     | 
    
         
            +
                  Client.sentinel(**options).new_client
         
     | 
| 
      
 141 
     | 
    
         
            +
                else
         
     | 
| 
      
 142 
     | 
    
         
            +
                  Client.config(**options).new_client
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
              end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
       264 
146 
     | 
    
         
             
              def synchronize
         
     | 
| 
       265 
147 
     | 
    
         
             
                @monitor.synchronize { yield(@client) }
         
     | 
| 
       266 
148 
     | 
    
         
             
              end
         
     | 
| 
       267 
149 
     | 
    
         | 
| 
       268 
150 
     | 
    
         
             
              def send_command(command, &block)
         
     | 
| 
       269 
151 
     | 
    
         
             
                @monitor.synchronize do
         
     | 
| 
       270 
     | 
    
         
            -
                  @client. 
     | 
| 
      
 152 
     | 
    
         
            +
                  @client.call_v(command, &block)
         
     | 
| 
       271 
153 
     | 
    
         
             
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
              rescue ::RedisClient::Error => error
         
     | 
| 
      
 155 
     | 
    
         
            +
                Client.translate_error!(error)
         
     | 
| 
       272 
156 
     | 
    
         
             
              end
         
     | 
| 
       273 
157 
     | 
    
         | 
| 
       274 
158 
     | 
    
         
             
              def send_blocking_command(command, timeout, &block)
         
     | 
| 
       275 
159 
     | 
    
         
             
                @monitor.synchronize do
         
     | 
| 
       276 
     | 
    
         
            -
                  @client. 
     | 
| 
      
 160 
     | 
    
         
            +
                  @client.blocking_call_v(timeout, command, &block)
         
     | 
| 
       277 
161 
     | 
    
         
             
                end
         
     | 
| 
       278 
162 
     | 
    
         
             
              end
         
     | 
| 
       279 
163 
     | 
    
         | 
| 
       280 
164 
     | 
    
         
             
              def _subscription(method, timeout, channels, block)
         
     | 
| 
       281 
     | 
    
         
            -
                 
     | 
| 
      
 165 
     | 
    
         
            +
                if block
         
     | 
| 
      
 166 
     | 
    
         
            +
                  if @subscription_client
         
     | 
| 
      
 167 
     | 
    
         
            +
                    raise SubscriptionError, "This client is already subscribed"
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
       282 
169 
     | 
    
         | 
| 
       283 
     | 
    
         
            -
             
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
             
     | 
| 
      
 170 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 171 
     | 
    
         
            +
                    @subscription_client = SubscribedClient.new(@client.pubsub)
         
     | 
| 
      
 172 
     | 
    
         
            +
                    if timeout > 0
         
     | 
| 
      
 173 
     | 
    
         
            +
                      @subscription_client.send(method, timeout, *channels, &block)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    else
         
     | 
| 
      
 175 
     | 
    
         
            +
                      @subscription_client.send(method, *channels, &block)
         
     | 
| 
      
 176 
     | 
    
         
            +
                    end
         
     | 
| 
      
 177 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 178 
     | 
    
         
            +
                    @subscription_client = nil
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
                else
         
     | 
| 
      
 181 
     | 
    
         
            +
                  unless @subscription_client
         
     | 
| 
      
 182 
     | 
    
         
            +
                    raise SubscriptionError, "This client is not subscribed"
         
     | 
| 
       289 
183 
     | 
    
         
             
                  end
         
     | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
       291 
     | 
    
         
            -
                  @ 
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                  @subscription_client.call_v([method].concat(channels))
         
     | 
| 
       292 
186 
     | 
    
         
             
                end
         
     | 
| 
       293 
187 
     | 
    
         
             
              end
         
     | 
| 
       294 
188 
     | 
    
         
             
            end
         
     | 
| 
       295 
189 
     | 
    
         | 
| 
       296 
190 
     | 
    
         
             
            require "redis/version"
         
     | 
| 
       297 
     | 
    
         
            -
            require "redis/connection"
         
     | 
| 
       298 
191 
     | 
    
         
             
            require "redis/client"
         
     | 
| 
       299 
     | 
    
         
            -
            require "redis/cluster"
         
     | 
| 
       300 
192 
     | 
    
         
             
            require "redis/pipeline"
         
     | 
| 
       301 
193 
     | 
    
         
             
            require "redis/subscribe"
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: redis
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.0.8
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Ezra Zygmuntowicz
         
     | 
| 
         @@ -16,50 +16,22 @@ authors: 
     | 
|
| 
       16 
16 
     | 
    
         
             
            autorequire:
         
     | 
| 
       17 
17 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       18 
18 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       19 
     | 
    
         
            -
            date:  
     | 
| 
      
 19 
     | 
    
         
            +
            date: 2023-10-23 00:00:00.000000000 Z
         
     | 
| 
       20 
20 
     | 
    
         
             
            dependencies:
         
     | 
| 
       21 
21 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       22 
     | 
    
         
            -
              name:  
     | 
| 
      
 22 
     | 
    
         
            +
              name: redis-client
         
     | 
| 
       23 
23 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       24 
24 
     | 
    
         
             
                requirements:
         
     | 
| 
       25 
25 
     | 
    
         
             
                - - ">="
         
     | 
| 
       26 
26 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       27 
     | 
    
         
            -
                    version:  
     | 
| 
       28 
     | 
    
         
            -
              type: : 
     | 
| 
      
 27 
     | 
    
         
            +
                    version: 0.17.0
         
     | 
| 
      
 28 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
       29 
29 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       30 
30 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       31 
31 
     | 
    
         
             
                requirements:
         
     | 
| 
       32 
32 
     | 
    
         
             
                - - ">="
         
     | 
| 
       33 
33 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       34 
     | 
    
         
            -
                    version:  
     | 
| 
       35 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       36 
     | 
    
         
            -
              name: hiredis
         
     | 
| 
       37 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       38 
     | 
    
         
            -
                requirements:
         
     | 
| 
       39 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       40 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       41 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       42 
     | 
    
         
            -
              type: :development
         
     | 
| 
       43 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       44 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       45 
     | 
    
         
            -
                requirements:
         
     | 
| 
       46 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       47 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       48 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       49 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       50 
     | 
    
         
            -
              name: mocha
         
     | 
| 
       51 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       52 
     | 
    
         
            -
                requirements:
         
     | 
| 
       53 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       54 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       55 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       56 
     | 
    
         
            -
              type: :development
         
     | 
| 
       57 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       58 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       59 
     | 
    
         
            -
                requirements:
         
     | 
| 
       60 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       61 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       62 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
      
 34 
     | 
    
         
            +
                    version: 0.17.0
         
     | 
| 
       63 
35 
     | 
    
         
             
            description: |2
         
     | 
| 
       64 
36 
     | 
    
         
             
                  A Ruby client that tries to match Redis' API one-to-one, while still
         
     | 
| 
       65 
37 
     | 
    
         
             
                  providing an idiomatic interface.
         
     | 
| 
         @@ -74,16 +46,6 @@ files: 
     | 
|
| 
       74 
46 
     | 
    
         
             
            - README.md
         
     | 
| 
       75 
47 
     | 
    
         
             
            - lib/redis.rb
         
     | 
| 
       76 
48 
     | 
    
         
             
            - lib/redis/client.rb
         
     | 
| 
       77 
     | 
    
         
            -
            - lib/redis/cluster.rb
         
     | 
| 
       78 
     | 
    
         
            -
            - lib/redis/cluster/command.rb
         
     | 
| 
       79 
     | 
    
         
            -
            - lib/redis/cluster/command_loader.rb
         
     | 
| 
       80 
     | 
    
         
            -
            - lib/redis/cluster/key_slot_converter.rb
         
     | 
| 
       81 
     | 
    
         
            -
            - lib/redis/cluster/node.rb
         
     | 
| 
       82 
     | 
    
         
            -
            - lib/redis/cluster/node_key.rb
         
     | 
| 
       83 
     | 
    
         
            -
            - lib/redis/cluster/node_loader.rb
         
     | 
| 
       84 
     | 
    
         
            -
            - lib/redis/cluster/option.rb
         
     | 
| 
       85 
     | 
    
         
            -
            - lib/redis/cluster/slot.rb
         
     | 
| 
       86 
     | 
    
         
            -
            - lib/redis/cluster/slot_loader.rb
         
     | 
| 
       87 
49 
     | 
    
         
             
            - lib/redis/commands.rb
         
     | 
| 
       88 
50 
     | 
    
         
             
            - lib/redis/commands/bitmaps.rb
         
     | 
| 
       89 
51 
     | 
    
         
             
            - lib/redis/commands/cluster.rb
         
     | 
| 
         @@ -101,12 +63,6 @@ files: 
     | 
|
| 
       101 
63 
     | 
    
         
             
            - lib/redis/commands/streams.rb
         
     | 
| 
       102 
64 
     | 
    
         
             
            - lib/redis/commands/strings.rb
         
     | 
| 
       103 
65 
     | 
    
         
             
            - lib/redis/commands/transactions.rb
         
     | 
| 
       104 
     | 
    
         
            -
            - lib/redis/connection.rb
         
     | 
| 
       105 
     | 
    
         
            -
            - lib/redis/connection/command_helper.rb
         
     | 
| 
       106 
     | 
    
         
            -
            - lib/redis/connection/hiredis.rb
         
     | 
| 
       107 
     | 
    
         
            -
            - lib/redis/connection/registry.rb
         
     | 
| 
       108 
     | 
    
         
            -
            - lib/redis/connection/ruby.rb
         
     | 
| 
       109 
     | 
    
         
            -
            - lib/redis/connection/synchrony.rb
         
     | 
| 
       110 
66 
     | 
    
         
             
            - lib/redis/distributed.rb
         
     | 
| 
       111 
67 
     | 
    
         
             
            - lib/redis/errors.rb
         
     | 
| 
       112 
68 
     | 
    
         
             
            - lib/redis/hash_ring.rb
         
     | 
| 
         @@ -119,9 +75,9 @@ licenses: 
     | 
|
| 
       119 
75 
     | 
    
         
             
            metadata:
         
     | 
| 
       120 
76 
     | 
    
         
             
              bug_tracker_uri: https://github.com/redis/redis-rb/issues
         
     | 
| 
       121 
77 
     | 
    
         
             
              changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
         
     | 
| 
       122 
     | 
    
         
            -
              documentation_uri: https://www.rubydoc.info/gems/redis/ 
     | 
| 
      
 78 
     | 
    
         
            +
              documentation_uri: https://www.rubydoc.info/gems/redis/5.0.8
         
     | 
| 
       123 
79 
     | 
    
         
             
              homepage_uri: https://github.com/redis/redis-rb
         
     | 
| 
       124 
     | 
    
         
            -
              source_code_uri: https://github.com/redis/redis-rb/tree/ 
     | 
| 
      
 80 
     | 
    
         
            +
              source_code_uri: https://github.com/redis/redis-rb/tree/v5.0.8
         
     | 
| 
       125 
81 
     | 
    
         
             
            post_install_message:
         
     | 
| 
       126 
82 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       127 
83 
     | 
    
         
             
            require_paths:
         
     | 
| 
         @@ -130,14 +86,14 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       130 
86 
     | 
    
         
             
              requirements:
         
     | 
| 
       131 
87 
     | 
    
         
             
              - - ">="
         
     | 
| 
       132 
88 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       133 
     | 
    
         
            -
                  version: 2. 
     | 
| 
      
 89 
     | 
    
         
            +
                  version: 2.5.0
         
     | 
| 
       134 
90 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       135 
91 
     | 
    
         
             
              requirements:
         
     | 
| 
       136 
92 
     | 
    
         
             
              - - ">="
         
     | 
| 
       137 
93 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       138 
94 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       139 
95 
     | 
    
         
             
            requirements: []
         
     | 
| 
       140 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 96 
     | 
    
         
            +
            rubygems_version: 3.3.7
         
     | 
| 
       141 
97 
     | 
    
         
             
            signing_key:
         
     | 
| 
       142 
98 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       143 
99 
     | 
    
         
             
            summary: A Ruby client library for Redis
         
     | 
| 
         @@ -1,79 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require_relative '../errors'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            class Redis
         
     | 
| 
       6 
     | 
    
         
            -
              class Cluster
         
     | 
| 
       7 
     | 
    
         
            -
                # Keep details about Redis commands for Redis Cluster Client.
         
     | 
| 
       8 
     | 
    
         
            -
                # @see https://redis.io/commands/command
         
     | 
| 
       9 
     | 
    
         
            -
                class Command
         
     | 
| 
       10 
     | 
    
         
            -
                  def initialize(details)
         
     | 
| 
       11 
     | 
    
         
            -
                    @details = pick_details(details)
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  def extract_first_key(command)
         
     | 
| 
       15 
     | 
    
         
            -
                    i = determine_first_key_position(command)
         
     | 
| 
       16 
     | 
    
         
            -
                    return '' if i == 0
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                    key = command[i].to_s
         
     | 
| 
       19 
     | 
    
         
            -
                    hash_tag = extract_hash_tag(key)
         
     | 
| 
       20 
     | 
    
         
            -
                    hash_tag.empty? ? key : hash_tag
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                  def should_send_to_master?(command)
         
     | 
| 
       24 
     | 
    
         
            -
                    dig_details(command, :write)
         
     | 
| 
       25 
     | 
    
         
            -
                  end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                  def should_send_to_slave?(command)
         
     | 
| 
       28 
     | 
    
         
            -
                    dig_details(command, :readonly)
         
     | 
| 
       29 
     | 
    
         
            -
                  end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                  private
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                  def pick_details(details)
         
     | 
| 
       34 
     | 
    
         
            -
                    details.transform_values do |detail|
         
     | 
| 
       35 
     | 
    
         
            -
                      {
         
     | 
| 
       36 
     | 
    
         
            -
                        first_key_position: detail[:first],
         
     | 
| 
       37 
     | 
    
         
            -
                        write: detail[:flags].include?('write'),
         
     | 
| 
       38 
     | 
    
         
            -
                        readonly: detail[:flags].include?('readonly')
         
     | 
| 
       39 
     | 
    
         
            -
                      }
         
     | 
| 
       40 
     | 
    
         
            -
                    end
         
     | 
| 
       41 
     | 
    
         
            -
                  end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  def dig_details(command, key)
         
     | 
| 
       44 
     | 
    
         
            -
                    name = command.first.to_s
         
     | 
| 
       45 
     | 
    
         
            -
                    return unless @details.key?(name)
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                    @details.fetch(name).fetch(key)
         
     | 
| 
       48 
     | 
    
         
            -
                  end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  def determine_first_key_position(command)
         
     | 
| 
       51 
     | 
    
         
            -
                    case command.first.to_s.downcase
         
     | 
| 
       52 
     | 
    
         
            -
                    when 'eval', 'evalsha', 'migrate', 'zinterstore', 'zunionstore' then 3
         
     | 
| 
       53 
     | 
    
         
            -
                    when 'object' then 2
         
     | 
| 
       54 
     | 
    
         
            -
                    when 'memory'
         
     | 
| 
       55 
     | 
    
         
            -
                      command[1].to_s.casecmp('usage').zero? ? 2 : 0
         
     | 
| 
       56 
     | 
    
         
            -
                    when 'xread', 'xreadgroup'
         
     | 
| 
       57 
     | 
    
         
            -
                      determine_optional_key_position(command, 'streams')
         
     | 
| 
       58 
     | 
    
         
            -
                    else
         
     | 
| 
       59 
     | 
    
         
            -
                      dig_details(command, :first_key_position).to_i
         
     | 
| 
       60 
     | 
    
         
            -
                    end
         
     | 
| 
       61 
     | 
    
         
            -
                  end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                  def determine_optional_key_position(command, option_name)
         
     | 
| 
       64 
     | 
    
         
            -
                    idx = command.map(&:to_s).map(&:downcase).index(option_name)
         
     | 
| 
       65 
     | 
    
         
            -
                    idx.nil? ? 0 : idx + 1
         
     | 
| 
       66 
     | 
    
         
            -
                  end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                  # @see https://redis.io/topics/cluster-spec#keys-hash-tags Keys hash tags
         
     | 
| 
       69 
     | 
    
         
            -
                  def extract_hash_tag(key)
         
     | 
| 
       70 
     | 
    
         
            -
                    s = key.index('{')
         
     | 
| 
       71 
     | 
    
         
            -
                    e = key.index('}', s.to_i + 1)
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                    return '' if s.nil? || e.nil?
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                    key[s + 1..e - 1]
         
     | 
| 
       76 
     | 
    
         
            -
                  end
         
     | 
| 
       77 
     | 
    
         
            -
                end
         
     | 
| 
       78 
     | 
    
         
            -
              end
         
     | 
| 
       79 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,33 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require 'redis/errors'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            class Redis
         
     | 
| 
       6 
     | 
    
         
            -
              class Cluster
         
     | 
| 
       7 
     | 
    
         
            -
                # Load details about Redis commands for Redis Cluster Client
         
     | 
| 
       8 
     | 
    
         
            -
                # @see https://redis.io/commands/command
         
     | 
| 
       9 
     | 
    
         
            -
                module CommandLoader
         
     | 
| 
       10 
     | 
    
         
            -
                  module_function
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  def load(nodes)
         
     | 
| 
       13 
     | 
    
         
            -
                    errors = nodes.map do |node|
         
     | 
| 
       14 
     | 
    
         
            -
                      begin
         
     | 
| 
       15 
     | 
    
         
            -
                        return fetch_command_details(node)
         
     | 
| 
       16 
     | 
    
         
            -
                      rescue CannotConnectError, ConnectionError, CommandError => error
         
     | 
| 
       17 
     | 
    
         
            -
                        error
         
     | 
| 
       18 
     | 
    
         
            -
                      end
         
     | 
| 
       19 
     | 
    
         
            -
                    end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                    raise InitialSetupError, errors
         
     | 
| 
       22 
     | 
    
         
            -
                  end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                  def fetch_command_details(node)
         
     | 
| 
       25 
     | 
    
         
            -
                    node.call(%i[command]).map do |reply|
         
     | 
| 
       26 
     | 
    
         
            -
                      [reply[0], { arity: reply[1], flags: reply[2], first: reply[3], last: reply[4], step: reply[5] }]
         
     | 
| 
       27 
     | 
    
         
            -
                    end.to_h
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  private_class_method :fetch_command_details
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
              end
         
     | 
| 
       33 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,72 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            class Redis
         
     | 
| 
       4 
     | 
    
         
            -
              class Cluster
         
     | 
| 
       5 
     | 
    
         
            -
                # Key to slot converter for Redis Cluster Client
         
     | 
| 
       6 
     | 
    
         
            -
                #
         
     | 
| 
       7 
     | 
    
         
            -
                # We can test it by `CLUSTER KEYSLOT` command.
         
     | 
| 
       8 
     | 
    
         
            -
                #
         
     | 
| 
       9 
     | 
    
         
            -
                # @see https://github.com/antirez/redis-rb-cluster
         
     | 
| 
       10 
     | 
    
         
            -
                #   Reference implementation in Ruby
         
     | 
| 
       11 
     | 
    
         
            -
                # @see https://redis.io/topics/cluster-spec#appendix
         
     | 
| 
       12 
     | 
    
         
            -
                #   Reference implementation in ANSI C
         
     | 
| 
       13 
     | 
    
         
            -
                # @see https://redis.io/commands/cluster-keyslot
         
     | 
| 
       14 
     | 
    
         
            -
                #   CLUSTER KEYSLOT command reference
         
     | 
| 
       15 
     | 
    
         
            -
                #
         
     | 
| 
       16 
     | 
    
         
            -
                # Copyright (C) 2013 Salvatore Sanfilippo <antirez@gmail.com>
         
     | 
| 
       17 
     | 
    
         
            -
                module KeySlotConverter
         
     | 
| 
       18 
     | 
    
         
            -
                  XMODEM_CRC16_LOOKUP = [
         
     | 
| 
       19 
     | 
    
         
            -
                    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
         
     | 
| 
       20 
     | 
    
         
            -
                    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
         
     | 
| 
       21 
     | 
    
         
            -
                    0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
         
     | 
| 
       22 
     | 
    
         
            -
                    0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
         
     | 
| 
       23 
     | 
    
         
            -
                    0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
         
     | 
| 
       24 
     | 
    
         
            -
                    0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
         
     | 
| 
       25 
     | 
    
         
            -
                    0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
         
     | 
| 
       26 
     | 
    
         
            -
                    0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
         
     | 
| 
       27 
     | 
    
         
            -
                    0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
         
     | 
| 
       28 
     | 
    
         
            -
                    0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
         
     | 
| 
       29 
     | 
    
         
            -
                    0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
         
     | 
| 
       30 
     | 
    
         
            -
                    0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
         
     | 
| 
       31 
     | 
    
         
            -
                    0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
         
     | 
| 
       32 
     | 
    
         
            -
                    0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
         
     | 
| 
       33 
     | 
    
         
            -
                    0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
         
     | 
| 
       34 
     | 
    
         
            -
                    0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
         
     | 
| 
       35 
     | 
    
         
            -
                    0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
         
     | 
| 
       36 
     | 
    
         
            -
                    0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
         
     | 
| 
       37 
     | 
    
         
            -
                    0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
         
     | 
| 
       38 
     | 
    
         
            -
                    0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
         
     | 
| 
       39 
     | 
    
         
            -
                    0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
         
     | 
| 
       40 
     | 
    
         
            -
                    0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
         
     | 
| 
       41 
     | 
    
         
            -
                    0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
         
     | 
| 
       42 
     | 
    
         
            -
                    0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
         
     | 
| 
       43 
     | 
    
         
            -
                    0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
         
     | 
| 
       44 
     | 
    
         
            -
                    0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
         
     | 
| 
       45 
     | 
    
         
            -
                    0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
         
     | 
| 
       46 
     | 
    
         
            -
                    0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
         
     | 
| 
       47 
     | 
    
         
            -
                    0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
         
     | 
| 
       48 
     | 
    
         
            -
                    0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
         
     | 
| 
       49 
     | 
    
         
            -
                    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
         
     | 
| 
       50 
     | 
    
         
            -
                    0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
         
     | 
| 
       51 
     | 
    
         
            -
                  ].freeze
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  HASH_SLOTS = 16_384
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                  module_function
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  # Convert key into slot.
         
     | 
| 
       58 
     | 
    
         
            -
                  #
         
     | 
| 
       59 
     | 
    
         
            -
                  # @param key [String] the key of the redis command
         
     | 
| 
       60 
     | 
    
         
            -
                  #
         
     | 
| 
       61 
     | 
    
         
            -
                  # @return [Integer] slot number
         
     | 
| 
       62 
     | 
    
         
            -
                  def convert(key)
         
     | 
| 
       63 
     | 
    
         
            -
                    crc = 0
         
     | 
| 
       64 
     | 
    
         
            -
                    key.each_byte do |b|
         
     | 
| 
       65 
     | 
    
         
            -
                      crc = ((crc << 8) & 0xffff) ^ XMODEM_CRC16_LOOKUP[((crc >> 8) ^ b) & 0xff]
         
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                    crc % HASH_SLOTS
         
     | 
| 
       69 
     | 
    
         
            -
                  end
         
     | 
| 
       70 
     | 
    
         
            -
                end
         
     | 
| 
       71 
     | 
    
         
            -
              end
         
     | 
| 
       72 
     | 
    
         
            -
            end
         
     |