Class: Moped::Node Private
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Represents a client to a node in a server cluster.
Instance Attribute Summary collapse
- #address ⇒ Object readonly private
- #address The address of the node.(Theaddressofthenode.) ⇒ Object readonly
- #down_at ⇒ Object readonly private
- #down_at The time the server node went down.(Thetimetheservernodewentdown.) ⇒ Object readonly
- #ip_address ⇒ Object readonly private
- #ip_address The node's ip.(Thenode's ip.) ⇒ Object readonly
- #peers ⇒ Object readonly private
- #peers Other peers in the replica set.(Otherpeers) ⇒ Object readonly
- #port ⇒ Object readonly private
- #port The connection port.(Theconnectionport.) ⇒ Object readonly
- #resolved_address ⇒ Object readonly private
- #resolved_address The host/port pair.(Thehost/portpair.) ⇒ Object readonly
- #timeout ⇒ Object readonly private
- #timeout The connection timeout.(Theconnectiontimeout.) ⇒ Object readonly
Instance Method Summary collapse
-
#==(other) ⇒ true, false
(also: #eql?)
private
Is this node equal to another?.
-
#apply_auth(credentials) ⇒ Node
private
Apply the authentication details to this node.
-
#arbiter? ⇒ true, false
private
Is the node an arbiter?.
-
#command(database, cmd, options = {}) ⇒ Hash
private
Execute a command against a database.
-
#disconnect ⇒ nil
private
Force the node to disconnect from the server.
-
#down? ⇒ Time?
private
Is the node down?.
-
#ensure_connected ⇒ nil
private
Yields the block if a connection can be established, retrying when a connection error is raised.
-
#ensure_primary ⇒ nil
private
Set a flag on the node for the duration of provided block so that an exception is raised if the node is no longer the primary node.
-
#get_more(database, collection, cursor_id, limit) ⇒ Message
private
Execute a get more operation on the node.
-
#hash ⇒ Integer
private
Get the hash identifier for the node.
-
#initialize(address) ⇒ Node
constructor
private
Creat the new node.
-
#insert(database, collection, documents, options = {}) ⇒ Message
private
Insert documents into the database.
- #inspect ⇒ Object private
-
#kill_cursors(cursor_ids) ⇒ Message
private
Kill all provided cursors on the node.
-
#needs_refresh?(time) ⇒ true, false
private
Does the node need to be refreshed?.
-
#passive? ⇒ true, false
private
Is the node passive?.
-
#pipeline ⇒ nil
private
Execute a pipeline of commands, for example a safe mode persist.
-
#primary? ⇒ true, false
private
Is the node the replica set primary?.
-
#query(database, collection, selector, options = {}) ⇒ Message
private
Execute a query on the node.
-
#refresh ⇒ nil
private
Nil.
-
#remove(database, collection, selector, options = {}) ⇒ Message
private
Execute a remove command for the provided selector.
-
#secondary? ⇒ true, false
private
Is the node a replica set secondary?.
-
#update(database, collection, selector, change, options = {}) ⇒ Message
private
Execute an update command for the provided selector.
Constructor Details
#initialize(address) ⇒ Node
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creat the new node.
227 228 229 230 231 232 233 234 235 |
# File 'lib/moped/node.rb', line 227 def initialize(address) @address = address @timeout = 5 @down_at = nil @refreshed_at = nil @primary = nil @secondary = nil resolve_address end |
Instance Attribute Details
#address ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def address @address end |
#address The address of the node.(Theaddressofthenode.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#down_at ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def down_at @down_at end |
#down_at The time the server node went down.(Thetimetheservernodewentdown.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#ip_address ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def ip_address @ip_address end |
#ip_address The node's ip.(Thenode's ip.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#peers ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def peers @peers end |
#peers Other peers in the replica set.(Otherpeers) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#port ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def port @port end |
#port The connection port.(Theconnectionport.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#resolved_address ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def resolved_address @resolved_address end |
#resolved_address The host/port pair.(Thehost/portpair.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
#timeout ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
15 16 17 |
# File 'lib/moped/node.rb', line 15 def timeout @timeout end |
#timeout The connection timeout.(Theconnectiontimeout.) ⇒ Object (readonly)
15 |
# File 'lib/moped/node.rb', line 15 attr_reader :address, :down_at, :ip_address, :peers, :port, :resolved_address, :timeout |
Instance Method Details
#==(other) ⇒ true, false Also known as: eql?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is this node equal to another?
27 28 29 |
# File 'lib/moped/node.rb', line 27 def ==(other) resolved_address == other.resolved_address end |
#apply_auth(credentials) ⇒ Node
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Apply the authentication details to this node.
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/moped/node.rb', line 42 def apply_auth(credentials) unless auth == credentials logouts = auth.keys - credentials.keys logouts.each { |database| logout(database) } credentials.each do |database, (username, password)| login(database, username, password) unless auth[database] == [username, password] end end self end |
#arbiter? ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the node an arbiter?
321 322 323 |
# File 'lib/moped/node.rb', line 321 def arbiter? @arbiter end |
#command(database, cmd, options = {}) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a command against a database.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/moped/node.rb', line 67 def command(database, cmd, = {}) operation = Protocol::Command.new(database, cmd, ) process(operation) do |reply| result = reply.documents[0] raise Errors::OperationFailure.new( operation, result ) if result["ok"] != 1 || result["err"] || result["errmsg"] result end end |
#disconnect ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Force the node to disconnect from the server.
84 85 86 87 |
# File 'lib/moped/node.rb', line 84 def disconnect auth.clear connection.disconnect end |
#down? ⇒ Time?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the node down?
97 98 99 |
# File 'lib/moped/node.rb', line 97 def down? @down_at end |
#ensure_connected ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Yields the block if a connection can be established, retrying when a connection error is raised.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/moped/node.rb', line 114 def ensure_connected # Don't run the reconnection login if we're already inside an # +ensure_connected+ block. return yield if Threaded.executing?(:connection) Threaded.begin(:connection) retry_on_failure = true begin connect unless connected? yield rescue Errors::ReplicaSetReconfigured # Someone else wrapped this in an #ensure_primary block, so let the # reconfiguration exception bubble up. raise rescue Errors::QueryFailure => e # We might have a replica set change with: # "failed with error 13435: "not master and slaveOk=false" if e.details['code'] == 13435 raise Errors::ReplicaSetReconfigured end raise rescue Errors::OperationFailure => e # We might have a replica set change with: # "failed with error 10054: "not master" if e.details['code'] == 10054 raise Errors::ReplicaSetReconfigured end raise rescue Errors::AuthenticationFailure, Errors::CursorNotFound # These exceptions are "expected" in the normal course of events, and # don't necessitate disconnecting. raise rescue Errors::ConnectionFailure disconnect if retry_on_failure # Maybe there was a hiccup -- try reconnecting one more time retry_on_failure = false retry else # Nope, we failed to connect twice. Flag the node as down and re-raise # the exception. down! raise end rescue # Looks like we got an unexpected error, so we'll clean up the connection # and re-raise the exception. disconnect raise $!.extend(Errors::SocketError) end ensure Threaded.end(:connection) end |
#ensure_primary ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Set a flag on the node for the duration of provided block so that an exception is raised if the node is no longer the primary node.
180 181 182 183 184 185 |
# File 'lib/moped/node.rb', line 180 def ensure_primary Threaded.begin(:ensure_primary) yield ensure Threaded.end(:ensure_primary) end |
#get_more(database, collection, cursor_id, limit) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a get more operation on the node.
201 202 203 204 205 |
# File 'lib/moped/node.rb', line 201 def get_more(database, collection, cursor_id, limit) reply = process(Protocol::GetMore.new(database, collection, cursor_id, limit)) raise Moped::Errors::CursorNotFound.new("GET MORE", cursor_id) if reply.cursor_not_found? reply end |
#hash ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get the hash identifier for the node.
215 216 217 |
# File 'lib/moped/node.rb', line 215 def hash resolved_address.hash end |
#insert(database, collection, documents, options = {}) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Insert documents into the database.
249 250 251 |
# File 'lib/moped/node.rb', line 249 def insert(database, collection, documents, = {}) process(Protocol::Insert.new(database, collection, documents, )) end |
#inspect ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
460 461 462 |
# File 'lib/moped/node.rb', line 460 def inspect "<#{self.class.name} resolved_address=#{@resolved_address.inspect}>" end |
#kill_cursors(cursor_ids) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Kill all provided cursors on the node.
263 264 265 |
# File 'lib/moped/node.rb', line 263 def kill_cursors(cursor_ids) process(Protocol::KillCursors.new(cursor_ids)) end |
#needs_refresh?(time) ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Does the node need to be refreshed?
277 278 279 |
# File 'lib/moped/node.rb', line 277 def needs_refresh?(time) !@refreshed_at || @refreshed_at < time end |
#passive? ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the node passive?
333 334 335 |
# File 'lib/moped/node.rb', line 333 def passive? @passive end |
#pipeline ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a pipeline of commands, for example a safe mode persist.
291 292 293 294 295 296 297 298 299 |
# File 'lib/moped/node.rb', line 291 def pipeline Threaded.begin(:pipeline) begin yield ensure Threaded.end(:pipeline) end flush unless Threaded.executing?(:pipeline) end |
#primary? ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the node the replica set primary?
309 310 311 |
# File 'lib/moped/node.rb', line 309 def primary? @primary end |
#query(database, collection, selector, options = {}) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a query on the node.
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/moped/node.rb', line 352 def query(database, collection, selector, = {}) operation = Protocol::Query.new(database, collection, selector, ) process(operation) do |reply| if reply.query_failed? if reply. && auth.has_key?(database) # If we got here, most likely this is the case of Moped # authenticating successfully against the node originally, but the # node has been reset or gone down and come back up. The most # common case here is a rs.stepDown() which will reinitialize the # connection. In this case we need to requthenticate and try again, # otherwise we'll just raise the error to the user. login(database, *auth[database]) query(database, collection, selector, ) else raise Errors::QueryFailure.new(operation, reply.documents.first) end end reply end end |
#refresh ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns nil.
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/moped/node.rb', line 388 def refresh if resolve_address info = command("admin", ismaster: 1) @refreshed_at = Time.now primary = true if info["ismaster"] secondary = true if info["secondary"] peers = [] peers.push(info["primary"]) if info["primary"] peers.concat(info["hosts"]) if info["hosts"] peers.concat(info["passives"]) if info["passives"] peers.concat(info["arbiters"]) if info["arbiters"] @peers = peers.map { |peer| Node.new(peer) } @primary, @secondary = primary, secondary @arbiter = info["arbiterOnly"] @passive = info["passive"] if !primary && Threaded.executing?(:ensure_primary) raise Errors::ReplicaSetReconfigured, "#{inspect} is no longer the primary node." end end end |
#remove(database, collection, selector, options = {}) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a remove command for the provided selector.
426 427 428 |
# File 'lib/moped/node.rb', line 426 def remove(database, collection, selector, = {}) process(Protocol::Delete.new(database, collection, selector, )) end |
#secondary? ⇒ true, false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the node a replica set secondary?
438 439 440 |
# File 'lib/moped/node.rb', line 438 def secondary? @secondary end |
#update(database, collection, selector, change, options = {}) ⇒ Message
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute an update command for the provided selector.
456 457 458 |
# File 'lib/moped/node.rb', line 456 def update(database, collection, selector, change, = {}) process(Protocol::Update.new(database, collection, selector, change, )) end |