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
-
#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.
55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/redis_failover/client.rb', line 55 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.
107 108 109 110 111 112 113 |
# File 'lib/redis_failover/client.rb', line 107 def method_missing(method, *args, &block) if redis_operation?(method) dispatch(method, *args, &block) else super end end |
Instance Method Details
#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.
80 81 82 |
# File 'lib/redis_failover/client.rb', line 80 def client(*args) self end |
#current_master ⇒ String
Retrieves the current redis master.
165 166 167 168 |
# File 'lib/redis_failover/client.rb', line 165 def current_master master = @lock.synchronize { @master } address_for(master) end |
#current_slaves ⇒ Array<String>
Retrieves the current redis slaves.
173 174 175 176 |
# File 'lib/redis_failover/client.rb', line 173 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.
125 126 127 |
# File 'lib/redis_failover/client.rb', line 125 def inspect "#<RedisFailover::Client (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.
88 89 90 |
# File 'lib/redis_failover/client.rb', line 88 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.
137 138 139 140 |
# File 'lib/redis_failover/client.rb', line 137 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.
102 103 104 |
# File 'lib/redis_failover/client.rb', line 102 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.
156 157 158 159 160 |
# File 'lib/redis_failover/client.rb', line 156 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.
120 121 122 |
# File 'lib/redis_failover/client.rb', line 120 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.
147 148 149 150 151 |
# File 'lib/redis_failover/client.rb', line 147 def shutdown @zk.close! if @zk @zk = nil purge_clients end |