Class: RedisFailover::Client
- Inherits:
-
Object
- Object
- RedisFailover::Client
- Includes:
- Util
- Defined in:
- lib/redis_failover/client.rb
Overview
Redis failover-aware client. RedisFailover::Client is a wrapper over a set of underlying redis clients, which means all normal redis operations can be performed on an instance of this class. The class only requires a set of ZooKeeper server addresses to function properly. The client will automatically retry failed operations, and handle failover to a new master. The client registers and listens for watcher events from the Node Manager. When these events are received, the client fetches the latest set of redis nodes from ZooKeeper and rebuilds its internal Redis clients appropriately. RedisFailover::Client also directs write operations to the master, and all read operations to the slaves.
Constant Summary collapse
- ZNODE_UPDATE_TIMEOUT =
Maximum allowed elapsed time between notifications from the Node Manager. When this timeout is reached, the client will raise a NoNodeManagerError and purge its internal redis clients.
9
- RETRY_WAIT_TIME =
Amount of time to sleep before retrying a failed operation.
3
Constants included from Util
Util::CONNECTIVITY_ERRORS, Util::DEFAULT_ROOT_ZNODE_PATH, Util::REDIS_ERRORS, Util::REDIS_READ_OPS, Util::UNSUPPORTED_OPS, Util::ZK_ERRORS
Instance Method Summary collapse
- #call(command, &block) ⇒ Object
-
#client(*args) ⇒ RedisFailover::Client
Stubs this method to return this RedisFailover::Client object.
-
#current_master ⇒ String
Retrieves the current redis master.
-
#current_slaves ⇒ Array<String>
Retrieves the current redis slaves.
-
#initialize(options = {}) {|_self| ... } ⇒ RedisFailover::Client
constructor
Creates a new failover redis client.
-
#inspect ⇒ String
(also: #to_s)
A string representation of the client.
-
#location ⇒ String
Delegates to the underlying Redis client to fetch the location.
-
#manual_failover(options = {}) ⇒ Object
Force a manual failover to a new server.
-
#method_missing(method, *args, &block) ⇒ Object
Dispatches redis operations to master/slaves.
-
#on_node_change(&callback) ⇒ Object
Specifies a callback to invoke when the current redis node list changes.
-
#reconnect ⇒ Object
Reconnect will first perform a shutdown of the underlying redis clients.
-
#respond_to_missing?(method, include_private) ⇒ Boolean
Determines whether or not an unknown method can be handled.
-
#shutdown ⇒ Object
Gracefully performs a shutdown of this client.
Methods included from Util
#decode, #different?, #encode, logger, #logger, logger=, #symbolize_keys
Constructor Details
#initialize(options = {}) {|_self| ... } ⇒ RedisFailover::Client
Use either :zkservers or :zk
Creates a new failover redis client.
62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/redis_failover/client.rb', line 62 def initialize( = {}) Util.logger = [:logger] if [:logger] @master = nil @slaves = [] @node_addresses = {} @lock = Monitor.new @current_client_key = "current-client-#{self.object_id}" yield self if block_given? () setup_zk build_clients end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Dispatches redis operations to master/slaves.
114 115 116 117 118 119 120 |
# File 'lib/redis_failover/client.rb', line 114 def method_missing(method, *args, &block) if redis_operation?(method) dispatch(method, *args, &block) else super end end |
Instance Method Details
#call(command, &block) ⇒ Object
39 40 41 42 43 |
# File 'lib/redis_failover/client.rb', line 39 def call(command, &block) method = command[0] args = command[1..-1] dispatch(method, *args, &block) end |
#client(*args) ⇒ RedisFailover::Client
Stubs this method to return this RedisFailover::Client object.
Some libraries (Resque) assume they can access the client
via this method,
but we don't want to actually ever expose the internal Redis connections.
By returning self
here, we can add stubs for functionality like #reconnect,
and everything will Just Work.
Takes an *args array for safety only.
87 88 89 |
# File 'lib/redis_failover/client.rb', line 87 def client(*args) self end |
#current_master ⇒ String
Retrieves the current redis master.
172 173 174 175 |
# File 'lib/redis_failover/client.rb', line 172 def current_master master = @lock.synchronize { @master } address_for(master) end |
#current_slaves ⇒ Array<String>
Retrieves the current redis slaves.
180 181 182 183 |
# File 'lib/redis_failover/client.rb', line 180 def current_slaves slaves = @lock.synchronize { @slaves } addresses_for(slaves) end |
#inspect ⇒ String Also known as: to_s
Returns a string representation of the client.
132 133 134 |
# File 'lib/redis_failover/client.rb', line 132 def inspect "#<RedisFailover::Client (db: #{@db.to_i}, master: #{master_name}, slaves: #{slave_names})>" end |
#location ⇒ String
Delegates to the underlying Redis client to fetch the location. This method always returns the location of the master.
95 96 97 |
# File 'lib/redis_failover/client.rb', line 95 def location dispatch(:client).location end |
#manual_failover(options = {}) ⇒ Object
Force a manual failover to a new server. A specific server can be specified via options. If no options are passed, a random slave will be selected as the candidate for the new master.
144 145 146 147 |
# File 'lib/redis_failover/client.rb', line 144 def manual_failover( = {}) ManualFailover.new(@zk, @root_znode, ).perform self end |
#on_node_change(&callback) ⇒ Object
Specifies a callback to invoke when the current redis node list changes.
109 110 111 |
# File 'lib/redis_failover/client.rb', line 109 def on_node_change(&callback) @on_node_change = callback end |
#reconnect ⇒ Object
Reconnect will first perform a shutdown of the underlying redis clients. Next, it attempts to reopen the ZooKeeper client and re-create the redis clients after it fetches the most up-to-date list from ZooKeeper.
163 164 165 166 167 |
# File 'lib/redis_failover/client.rb', line 163 def reconnect purge_clients @zk ? @zk.reopen : setup_zk build_clients end |
#respond_to_missing?(method, include_private) ⇒ Boolean
Determines whether or not an unknown method can be handled.
127 128 129 |
# File 'lib/redis_failover/client.rb', line 127 def respond_to_missing?(method, include_private) redis_operation?(method) || super end |
#shutdown ⇒ Object
Gracefully performs a shutdown of this client. This method is mostly useful when the client is used in a forking environment. When a fork occurs, you can call this method in an after_fork hook, and then create a new instance of the client. The underlying ZooKeeper client and redis clients will be closed.
154 155 156 157 158 |
# File 'lib/redis_failover/client.rb', line 154 def shutdown @zk.close! if @zk @zk = nil purge_clients end |