Class: Redis

Inherits:
Object
  • Object
show all
Includes:
Commands
Defined in:
lib/redis.rb,
lib/redis/client.rb,
lib/redis/errors.rb,
lib/redis/version.rb,
lib/redis/commands.rb,
lib/redis/pipeline.rb,
lib/redis/hash_ring.rb,
lib/redis/subscribe.rb,
lib/redis/distributed.rb,
lib/redis/commands/geo.rb,
lib/redis/lib_identity.rb,
lib/redis/commands/keys.rb,
lib/redis/commands/sets.rb,
lib/redis/commands/lists.rb,
lib/redis/commands/hashes.rb,
lib/redis/commands/pubsub.rb,
lib/redis/commands/server.rb,
lib/redis/commands/bitmaps.rb,
lib/redis/commands/cluster.rb,
lib/redis/commands/streams.rb,
lib/redis/commands/strings.rb,
lib/redis/commands/scripting.rb,
lib/redis/commands/connection.rb,
lib/redis/commands/sorted_sets.rb,
lib/redis/commands/modules/json.rb,
lib/redis/commands/transactions.rb,
lib/redis/commands/hyper_log_log.rb,
lib/redis/commands/modules/search.rb,
lib/redis/commands/modules/search/field.rb,
lib/redis/commands/modules/search/index.rb,
lib/redis/commands/modules/search/query.rb,
lib/redis/commands/modules/search/hybrid.rb,
lib/redis/commands/modules/search/result.rb,
lib/redis/commands/modules/search/schema.rb,
lib/redis/commands/modules/search/dialect.rb,
lib/redis/commands/modules/search/aggregation.rb,
lib/redis/commands/modules/search/miscellaneous.rb,
lib/redis/commands/modules/search/index_definition.rb

Defined Under Namespace

Modules: Commands, Connection, LibIdentity Classes: BaseConnectionError, BaseError, CannotConnectError, Client, CommandError, ConnectionError, Distributed, Future, FutureNotReady, HashRing, InheritedError, InvalidClientOptionError, MultiConnection, MultiFuture, NoScriptError, OutOfMemoryError, PermissionError, PipelinedConnection, ProtocolError, ReadOnlyError, SubscribedClient, Subscription, SubscriptionError, TimeoutError, WrongTypeError

Constant Summary collapse

BASE_PATH =
__dir__
Deprecated =
Class.new(StandardError)
SERVER_URL_OPTIONS =
%i(url host port path).freeze
VERSION =
'6.0.0'

Constants included from Commands

Commands::Boolify, Commands::BoolifySet, Commands::Floatify, Commands::FloatifyPair, Commands::FloatifyPairs, Commands::Hashify, Commands::HashifyClusterNodeInfo, Commands::HashifyClusterNodes, Commands::HashifyClusterSlaves, Commands::HashifyClusterSlots, Commands::HashifyInfo, Commands::HashifyStreamAutoclaim, Commands::HashifyStreamAutoclaimJustId, Commands::HashifyStreamEntries, Commands::HashifyStreamPendingDetails, Commands::HashifyStreamPendings, Commands::HashifyStreams, Commands::Noop, Commands::Pairify

Constants included from Commands::Search

Commands::Search::DEFAULT_DIALECT

Constants included from Commands::Json

Commands::Json::NumincrbyNormalize, Commands::Json::TypeNormalize

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Commands

#call, #sentinel

Methods included from Commands::Transactions

#discard, #exec, #multi, #unwatch, #watch

Methods included from Commands::Strings

#append, #decr, #decrby, #get, #getdel, #getex, #getrange, #getset, #incr, #incrby, #incrbyfloat, #mapped_mget, #mapped_mset, #mapped_msetnx, #mget, #mset, #msetnx, #psetex, #set, #setex, #setnx, #setrange, #strlen

Methods included from Commands::Streams

#xack, #xadd, #xautoclaim, #xclaim, #xdel, #xgroup, #xinfo, #xlen, #xpending, #xrange, #xread, #xreadgroup, #xrevrange, #xtrim

Methods included from Commands::SortedSets

#bzmpop, #bzpopmax, #bzpopmin, #zadd, #zcard, #zcount, #zdiff, #zdiffstore, #zincrby, #zinter, #zinterstore, #zlexcount, #zmpop, #zmscore, #zpopmax, #zpopmin, #zrandmember, #zrange, #zrangebylex, #zrangebyscore, #zrangestore, #zrank, #zrem, #zremrangebyrank, #zremrangebyscore, #zrevrange, #zrevrangebylex, #zrevrangebyscore, #zrevrank, #zscan, #zscan_each, #zscore, #zunion, #zunionstore

Methods included from Commands::Sets

#sadd, #sadd?, #scard, #sdiff, #sdiffcard, #sdiffstore, #sinter, #sinterstore, #sismember, #smembers, #smismember, #smove, #spop, #srandmember, #srem, #srem?, #sscan, #sscan_each, #sunion, #sunioncard, #sunionstore

Methods included from Commands::Server

#bgrewriteaof, #bgsave, #client, #config, #dbsize, #debug, #flushall, #flushdb, #info, #lastsave, #monitor, #save, #shutdown, #slaveof, #slowlog, #sync, #time

Methods included from Commands::Search

#create_index, #ft_aggregate, #ft_aliasadd, #ft_aliasdel, #ft_aliaslist, #ft_aliasupdate, #ft_alter, #ft_config_get, #ft_config_set, #ft_create, #ft_cursor_del, #ft_cursor_read, #ft_dictadd, #ft_dictdel, #ft_dictdump, #ft_dropindex, #ft_explain, #ft_hybrid_search, #ft_info, #ft_profile, #ft_search, #ft_spellcheck, #ft_sugadd, #ft_sugdel, #ft_sugget, #ft_suglen, #ft_syndump, #ft_synupdate, #ft_tagvals

Methods included from Commands::Scripting

#eval, #evalsha, #script

Methods included from Commands::Pubsub

#psubscribe, #psubscribe_with_timeout, #publish, #pubsub, #punsubscribe, #spublish, #ssubscribe, #ssubscribe_with_timeout, #subscribe, #subscribe_with_timeout, #subscribed?, #sunsubscribe, #unsubscribe

Methods included from Commands::Json

#json_arrappend, #json_arrindex, #json_arrinsert, #json_arrlen, #json_arrpop, #json_arrtrim, #json_clear, #json_debug_memory, #json_del, #json_forget, #json_get, #json_merge, #json_mget, #json_mset, #json_numincrby, #json_objkeys, #json_objlen, #json_set, #json_strappend, #json_strlen, #json_toggle, #json_type

Methods included from Commands::Lists

#blmove, #blmovem, #blmpop, #blpop, #brpop, #brpoplpush, #lindex, #linsert, #llen, #lmove, #lmovem, #lmpop, #lpop, #lpush, #lpushx, #lrange, #lrem, #lset, #ltrim, #rpop, #rpoplpush, #rpush, #rpushx

Methods included from Commands::Keys

#copy, #del, #dump, #exists, #exists?, #expire, #expireat, #expiretime, #keys, #migrate, #move, #object, #persist, #pexpire, #pexpireat, #pexpiretime, #pttl, #randomkey, #rename, #renamenx, #restore, #scan, #scan_each, #sort, #ttl, #type, #unlink

Methods included from Commands::HyperLogLog

#pfadd, #pfcount, #pfmerge

Methods included from Commands::Hashes

#hdel, #hexists, #hexpire, #hget, #hgetall, #hincrby, #hincrbyfloat, #hkeys, #hlen, #hmget, #hmset, #hpexpire, #hpttl, #hrandfield, #hscan, #hscan_each, #hset, #hsetnx, #httl, #hvals, #mapped_hmget, #mapped_hmset

Methods included from Commands::Geo

#geoadd, #geodist, #geohash, #geopos, #georadius, #georadiusbymember, #geosearch, #geosearchstore

Methods included from Connection

drivers

Methods included from Commands::Cluster

#asking, #cluster

Methods included from Commands::Bitmaps

#bitcount, #bitop, #bitpos, #getbit, #setbit

Constructor Details

#initialize(options = {}) ⇒ Redis

Create a new client instance

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :url (String) — default: value of the environment variable REDIS_URL

    a Redis URL, for a TCP connection: redis://:[password]@[hostname]:[port]/[db] (password, port and database are optional), for a unix socket connection: unix://[path to Redis socket]. This overrides all other options.

  • :host (String) — default: "127.0.0.1"

    server hostname

  • :port (Integer) — default: 6379

    server port

  • :path (String)

    path to server socket (overrides host and port)

  • :timeout (Float) — default: 1.0

    timeout in seconds

  • :connect_timeout (Float) — default: same as timeout

    timeout for initial connect in seconds

  • :username (String)

    Username to authenticate against server

  • :password (String)

    Password to authenticate against server

  • :db (Integer) — default: 0

    Database to select after connect and on reconnects

  • :driver (Symbol)

    Driver to use, currently supported: :ruby, :hiredis

  • :protocol (Integer) — default: 3

    RESP protocol version to negotiate (HELLO). Defaults to RESP3; set to 2 for RESP2. Servers without RESP3 support automatically fall back to RESP2.

  • :id (String)

    ID for the client connection, assigns name to current connection by sending CLIENT SETNAME

  • :driver_info (String, Array<String>, false)

    Identity a library built on top of redis-rb reports to the server via CLIENT SETINFO, shown as lib-name=redis-rb(<driver_info>) in CLIENT LIST. The recommended format is <name>_v<version>; an Array is joined with ;. Pass false to disable client identification entirely.

  • :reconnect_attempts (Integer, Array<Integer, Float>)

    Number of attempts trying to connect, or a list of sleep duration between attempts.

  • :inherit_socket (Boolean) — default: false

    Whether to use socket in forked process or not

  • :name (String)

    The name of the server group to connect to.

  • :sentinels (Array)

    List of sentinels to contact



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/redis.rb', line 71

def initialize(options = {})
  @monitor = Monitor.new
  @options = options.dup
  @options[:reconnect_attempts] = 1 unless @options.key?(:reconnect_attempts)
  if ENV["REDIS_URL"] && SERVER_URL_OPTIONS.none? { |o| @options.key?(o) }
    @options[:url] = ENV["REDIS_URL"]
  end
  # Kept as state, not just a local: the RESP3->RESP2 fallback rebuilds @client and must re-apply
  # socket inheritance, otherwise fork safety would be silently lost after a downgrade.
  @inherit_socket = @options.delete(:inherit_socket)
  # HIMPORT fieldsets are server session state that dies with the physical connection; the
  # registry remembers each prepared schema so a lost session can be repaired (see the
  # himport_* overrides below). Deleted from @options so it never reaches RedisClient::Config.
  @himport_auto_prepare = @options.delete(:himport_auto_prepare) != false
  @himport_fieldsets = {}
  @subscription_client = nil

  @client = build_client
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Redis::Commands

Class Attribute Details

.raise_deprecationsObject

Returns the value of attribute raise_deprecations.



14
15
16
# File 'lib/redis.rb', line 14

def raise_deprecations
  @raise_deprecations
end

.silence_deprecationsObject

Returns the value of attribute silence_deprecations.



14
15
16
# File 'lib/redis.rb', line 14

def silence_deprecations
  @silence_deprecations
end

Class Method Details

.deprecate!(message) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/redis.rb', line 16

def deprecate!(message)
  unless silence_deprecations
    if raise_deprecations
      raise Deprecated, message
    else
      ::Kernel.warn(message)
    end
  end
end

Instance Method Details

#_clientObject



119
120
121
# File 'lib/redis.rb', line 119

def _client
  @client
end

#closeObject Also known as: disconnect!

Disconnect the client as quickly and silently as possible.



109
110
111
112
# File 'lib/redis.rb', line 109

def close
  @client.close
  @subscription_client&.close
end

#connected?Boolean

Test whether or not the client is connected

Returns:

  • (Boolean)


104
105
106
# File 'lib/redis.rb', line 104

def connected?
  @client.connected? || @subscription_client&.connected?
end

#connectionObject



146
147
148
149
150
151
152
153
154
# File 'lib/redis.rb', line 146

def connection
  {
    host: @client.host,
    port: @client.port,
    db: @client.db,
    id: id,
    location: "#{@client.host}:#{@client.port}"
  }
end

#dupObject



139
140
141
142
143
144
# File 'lib/redis.rb', line 139

def dup
  # inherit_socket and himport_auto_prepare are stripped from @options before the client config
  # is built (RedisClient::Config doesn't know them); merge the live values back so the
  # duplicate keeps the caller's settings instead of silently reverting to defaults.
  self.class.new(@options.merge(inherit_socket: @inherit_socket, himport_auto_prepare: @himport_auto_prepare))
end

#himport_discard(fieldset_name) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/redis.rb', line 193

def himport_discard(fieldset_name)
  @monitor.synchronize do
    reply = super
    @himport_fieldsets.delete(fieldset_name.to_s)
    reply
  end
end

#himport_discard_allObject



201
202
203
204
205
206
207
# File 'lib/redis.rb', line 201

def himport_discard_all
  @monitor.synchronize do
    reply = super
    @himport_fieldsets.clear
    reply
  end
end

#himport_prepare(fieldset_name, *fields) ⇒ Object

Each method holds @monitor across the server command AND its registry mutation: the two must be atomic with respect to other threads, otherwise a himport_set failing between another thread's DISCARD reply and its registry delete would still see the schema and re-prepare, resurrecting the fieldset the discard just removed. @monitor is reentrant, so the nested send_command/himport_prepare calls re-enter it safely.



171
172
173
174
175
176
177
178
# File 'lib/redis.rb', line 171

def himport_prepare(fieldset_name, *fields)
  fields.flatten!(1)
  @monitor.synchronize do
    reply = super(fieldset_name, fields)
    @himport_fieldsets[fieldset_name.to_s] = fields.dup.freeze
    reply
  end
end

#himport_set(key, fieldset_name, *values) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/redis.rb', line 180

def himport_set(key, fieldset_name, *values)
  @monitor.synchronize do
    super
  rescue CommandError => error
    fields = @himport_fieldsets[fieldset_name.to_s]
    raise unless @himport_auto_prepare && fields && error.message.include?("no such fieldset")

    himport_prepare(fieldset_name, fields)
    # `super` (not himport_set) so a second failure propagates instead of recovering again.
    super
  end
end

#idObject



131
132
133
# File 'lib/redis.rb', line 131

def id
  @client.id || @client.server_url
end

#inspectObject



135
136
137
# File 'lib/redis.rb', line 135

def inspect
  "#<Redis client v#{Redis::VERSION} for #{id}>"
end

#pipelined(exception: true) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/redis.rb', line 123

def pipelined(exception: true)
  synchronize do |client|
    client.pipelined(exception: exception) do |raw_pipeline|
      yield PipelinedConnection.new(raw_pipeline, exception: exception)
    end
  end
end

#with {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:

  • _self (Redis)

    the object that the method was called on



115
116
117
# File 'lib/redis.rb', line 115

def with
  yield self
end

#without_reconnect(&block) ⇒ Object

Run code without the client reconnecting



92
93
94
95
96
97
98
99
100
101
# File 'lib/redis.rb', line 92

def without_reconnect(&block)
  # Route through #synchronize like every other @client access: it holds @monitor and applies the
  # RESP3->RESP2 fallback. disable_reconnection establishes the connection eagerly, so if that
  # handshake fails the fallback rebuilds @client and the whole block re-runs against the new
  # (RESP2) client — keeping disable_reconnection bound to the live @client rather than a discarded
  # one. Referencing the block argument (not @client) is what makes the retry pick up the rebuild.
  synchronize do |client|
    client.disable_reconnection(&block)
  end
end