Class: Mongo::Connection
Overview
Instantiates and manages connections to MongoDB.
Direct Known Subclasses
Constant Summary collapse
- TCPSocket =
::TCPSocket
- Mutex =
::Mutex
- ConditionVariable =
::ConditionVariable
- DEFAULT_PORT =
27017
- STANDARD_HEADER_SIZE =
16
- RESPONSE_HEADER_SIZE =
20
- @@current_request_id =
Counter for generating unique request ids.
0
Instance Attribute Summary collapse
-
#auths ⇒ Object
readonly
Returns the value of attribute auths.
-
#host_to_try ⇒ Object
readonly
Returns the value of attribute host_to_try.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#pool_size ⇒ Object
readonly
Returns the value of attribute pool_size.
-
#primary ⇒ Object
readonly
Returns the value of attribute primary.
-
#primary_pool ⇒ Object
readonly
Returns the value of attribute primary_pool.
-
#safe ⇒ Object
readonly
Returns the value of attribute safe.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
Class Method Summary collapse
-
.from_uri(string, extra_opts = {}) ⇒ Mongo::Connection, Mongo::ReplSetConnection
Initialize a connection to MongoDB using the MongoDB URI spec:.
- .multi(nodes, opts = {}) ⇒ Mongo::Connection deprecated Deprecated.
Instance Method Summary collapse
-
#[](db_name) ⇒ Mongo::DB
Shortcut for returning a database.
-
#active? ⇒ Boolean
Determine if the connection is active.
-
#add_auth(db_name, username, password) ⇒ Hash
Save an authentication to this connection.
-
#apply_saved_authentication(opts = {}) ⇒ Boolean
Apply each of the saved database authentications.
- #authenticate_pools ⇒ Object
-
#checkin_reader(socket) ⇒ Object
Checkin a socket used for reading.
-
#checkin_writer(socket) ⇒ Object
Checkin a socket used for writing.
-
#checkout_reader ⇒ Object
Checkout a socket for reading (i.e., a secondary node).
-
#checkout_writer ⇒ Object
Checkout a socket for writing (i.e., a primary node).
-
#clear_auths ⇒ true
Remove all authenication information stored in this connection.
-
#close ⇒ Object
Close the connection to the database.
-
#connect ⇒ Object
(also: #reconnect)
Create a new socket and attempt to connect to master.
-
#connected? ⇒ Boolean
It’s possible that we defined connected as all nodes being connected??? NOTE: Do check if this needs to be more stringent.
- #connecting? ⇒ Boolean
-
#copy_database(from, to, from_host = "localhost", username = nil, password = nil) ⇒ Object
Copy the database
from
toto
on localhost. -
#database_info ⇒ Hash
Return a hash with all database names and their respective sizes on disk.
-
#database_names ⇒ Array
Return an array of database names.
-
#db(db_name, opts = {}) ⇒ Mongo::DB
Return a database with the given name.
-
#drop_database(name) ⇒ Object
Drop a database.
-
#host ⇒ String
The host name used for this connection.
-
#initialize(host = nil, port = nil, opts = {}) ⇒ Connection
constructor
Create a connection to single MongoDB instance.
-
#instrument(name, payload = {}, &blk) ⇒ Object
Execute the block and log the operation described by name and payload.
-
#lock! ⇒ BSON::OrderedHash
Fsync, then lock the mongod process against writes.
-
#locked? ⇒ Boolean
Is this database locked against writes?.
- #logout_pools(db) ⇒ Object
-
#max_bson_size ⇒ Integer
Returns the maximum BSON object size as returned by the core server.
-
#ping ⇒ Hash
Checks if a server is alive.
-
#port ⇒ Integer
The port used for this connection.
-
#read_primary? ⇒ Boolean
(also: #primary?)
Determine whether we’re reading from a primary node.
-
#receive_message(operation, message, log_message = nil, socket = nil, command = false) ⇒ Array
Sends a message to the database and waits for the response.
-
#remove_auth(db_name) ⇒ Boolean
Remove a saved authentication for this connection.
-
#send_message(operation, message, opts = {}) ⇒ Integer
Send a message to MongoDB, adding the necessary headers.
-
#send_message_with_safe_check(operation, message, db_name, log_message = nil, last_error_params = false) ⇒ Hash
Sends a message to the database, waits for a response, and raises an exception if the operation has failed.
-
#server_info ⇒ Hash
Get the build information for the current connection.
-
#server_version ⇒ Mongo::ServerVersion
Get the build version of the current server.
-
#slave_ok? ⇒ Boolean
Is it okay to connect to a slave?.
-
#unlock! ⇒ BSON::OrderedHash
Unlock a previously fsync-locked mongod process.
Constructor Details
#initialize(host = nil, port = nil, opts = {}) ⇒ Connection
Create a connection to single MongoDB instance.
You may specify whether connection to slave is permitted. In all cases, the default host is “localhost” and the default port is 27017.
If you’re connecting to a replica set, you’ll need to use ReplSetConnection.new instead.
Once connected to a replica set, you can find out which nodes are primary, secondary, and arbiters with the corresponding accessors: Connection#primary, Connection#secondaries, and Connection#arbiters. This is useful if your application needs to connect manually to nodes other than the primary.
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/mongo/connection.rb', line 94 def initialize(host=nil, port=nil, opts={}) @host_to_try = format_pair(host, port) # Host and port of current master. @host = @port = nil # slave_ok can be true only if one node is specified @slave_ok = opts[:slave_ok] setup(opts) end |
Instance Attribute Details
#auths ⇒ Object (readonly)
Returns the value of attribute auths.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def auths @auths end |
#host_to_try ⇒ Object (readonly)
Returns the value of attribute host_to_try.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def host_to_try @host_to_try end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def logger @logger end |
#pool_size ⇒ Object (readonly)
Returns the value of attribute pool_size.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def pool_size @pool_size end |
#primary ⇒ Object (readonly)
Returns the value of attribute primary.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def primary @primary end |
#primary_pool ⇒ Object (readonly)
Returns the value of attribute primary_pool.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def primary_pool @primary_pool end |
#safe ⇒ Object (readonly)
Returns the value of attribute safe.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def safe @safe end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
38 39 40 |
# File 'lib/mongo/connection.rb', line 38 def size @size end |
Class Method Details
.from_uri(string, extra_opts = {}) ⇒ Mongo::Connection, Mongo::ReplSetConnection
Initialize a connection to MongoDB using the MongoDB URI spec:
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/mongo/connection.rb', line 147 def self.from_uri(string, extra_opts={}) uri = URIParser.new(string) opts = uri. opts.merge!(extra_opts) if uri.nodes.length == 1 opts.merge!({:auths => uri.auths}) Connection.new(uri.nodes[0][0], uri.nodes[0][1], opts) elsif uri.nodes.length > 1 nodes = uri.nodes.clone nodes_with_opts = nodes << opts ReplSetConnection.new(*nodes_with_opts) else raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node." end end |
.multi(nodes, opts = {}) ⇒ Mongo::Connection
DEPRECATED
Initialize a connection to a MongoDB replica set using an array of seed nodes.
The seed nodes specified will be used on the initial connection to the replica set, but note that this list of nodes will be replced by the list of canonical nodes returned by running the is_master command on the replica set.
132 133 134 135 136 137 |
# File 'lib/mongo/connection.rb', line 132 def self.multi(nodes, opts={}) warn "Connection.multi is now deprecated. Please use ReplSetConnection.new instead." nodes << opts ReplSetConnection.new(*nodes) end |
Instance Method Details
#[](db_name) ⇒ Mongo::DB
Shortcut for returning a database. Use DB#db to accept options.
310 311 312 |
# File 'lib/mongo/connection.rb', line 310 def [](db_name) DB.new(db_name, self, :safe => @safe) end |
#active? ⇒ Boolean
Determine if the connection is active. In a normal case the server_info operation will be performed without issues, but if the connection was dropped by the server or for some reason the sockets are unsynchronized, a ConnectionFailure will be raised and the return will be false.
542 543 544 545 546 547 548 549 550 |
# File 'lib/mongo/connection.rb', line 542 def active? return false unless connected? ping true rescue ConnectionFailure false end |
#add_auth(db_name, username, password) ⇒ Hash
Save an authentication to this connection. When connecting, the connection will attempt to re-authenticate on every db specificed in the list of auths. This method is called automatically by DB#authenticate.
Note: this method will not actually issue an authentication command. To do that, either run Connection#apply_saved_authentication or DB#authenticate.
232 233 234 235 236 237 238 239 240 |
# File 'lib/mongo/connection.rb', line 232 def add_auth(db_name, username, password) remove_auth(db_name) auth = {} auth['db_name'] = db_name auth['username'] = username auth['password'] = password @auths << auth auth end |
#apply_saved_authentication(opts = {}) ⇒ Boolean
Apply each of the saved database authentications.
210 211 212 213 214 215 216 217 |
# File 'lib/mongo/connection.rb', line 210 def apply_saved_authentication(opts={}) return false if @auths.empty? @auths.each do |auth| self[auth['db_name']].issue_authentication(auth['username'], auth['password'], false, :socket => opts[:socket]) end true end |
#authenticate_pools ⇒ Object
264 265 266 |
# File 'lib/mongo/connection.rb', line 264 def authenticate_pools @primary_pool.authenticate_existing end |
#checkin_reader(socket) ⇒ Object
Checkin a socket used for reading. Note: this is overridden in ReplSetConnection.
593 594 595 596 597 |
# File 'lib/mongo/connection.rb', line 593 def checkin_reader(socket) if @primary_pool @primary_pool.checkin(socket) end end |
#checkin_writer(socket) ⇒ Object
Checkin a socket used for writing. Note: this is overridden in ReplSetConnection.
601 602 603 604 605 |
# File 'lib/mongo/connection.rb', line 601 def checkin_writer(socket) if @primary_pool @primary_pool.checkin(socket) end end |
#checkout_reader ⇒ Object
Checkout a socket for reading (i.e., a secondary node). Note: this is overridden in ReplSetConnection.
579 580 581 582 |
# File 'lib/mongo/connection.rb', line 579 def checkout_reader connect unless connected? @primary_pool.checkout end |
#checkout_writer ⇒ Object
Checkout a socket for writing (i.e., a primary node). Note: this is overridden in ReplSetConnection.
586 587 588 589 |
# File 'lib/mongo/connection.rb', line 586 def checkout_writer connect unless connected? @primary_pool.checkout end |
#clear_auths ⇒ true
Remove all authenication information stored in this connection.
259 260 261 262 |
# File 'lib/mongo/connection.rb', line 259 def clear_auths @auths = [] true end |
#close ⇒ Object
Close the connection to the database.
562 563 564 565 566 |
# File 'lib/mongo/connection.rb', line 562 def close @primary_pool.close if @primary_pool @primary_pool = nil @primary = nil end |
#connect ⇒ Object Also known as: reconnect
Create a new socket and attempt to connect to master. If successful, sets host and port to master and returns the socket.
If connecting to a replica set, this method will replace the initially-provided seed list with any nodes known to the set.
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/mongo/connection.rb', line 503 def connect close config = check_is_master(@host_to_try) if config if config['ismaster'] == 1 || config['ismaster'] == true @read_primary = true elsif @slave_ok @read_primary = false end set_primary(@host_to_try) end if connected? BSON::BSON_CODER.update_max_bson_size(self) else raise ConnectionFailure, "Failed to connect to a master node at #{@host_to_try[0]}:#{@host_to_try[1]}" end end |
#connected? ⇒ Boolean
It’s possible that we defined connected as all nodes being connected??? NOTE: Do check if this needs to be more stringent. Probably not since if any node raises a connection failure, all nodes will be closed.
532 533 534 |
# File 'lib/mongo/connection.rb', line 532 def connected? @primary_pool && @primary_pool.host && @primary_pool.port end |
#connecting? ⇒ Boolean
525 526 527 |
# File 'lib/mongo/connection.rb', line 525 def connecting? @nodes_to_try.length > 0 end |
#copy_database(from, to, from_host = "localhost", username = nil, password = nil) ⇒ Object
Copy the database from
to to
on localhost. The from
database is assumed to be on localhost, but an alternate host can be specified.
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/mongo/connection.rb', line 329 def copy_database(from, to, from_host="localhost", username=nil, password=nil) oh = BSON::OrderedHash.new oh[:copydb] = 1 oh[:fromhost] = from_host oh[:fromdb] = from oh[:todb] = to if username || password unless username && password raise MongoArgumentError, "Both username and password must be supplied for authentication." end nonce_cmd = BSON::OrderedHash.new nonce_cmd[:copydbgetnonce] = 1 nonce_cmd[:fromhost] = from_host result = self["admin"].command(nonce_cmd) oh[:nonce] = result["nonce"] oh[:username] = username oh[:key] = Mongo::Support.auth_key(username, password, oh[:nonce]) end self["admin"].command(oh) end |
#database_info ⇒ Hash
Return a hash with all database names and their respective sizes on disk.
276 277 278 279 280 281 |
# File 'lib/mongo/connection.rb', line 276 def database_info doc = self['admin'].command({:listDatabases => 1}) doc['databases'].each_with_object({}) do |db, info| info[db['name']] = db['sizeOnDisk'].to_i end end |
#database_names ⇒ Array
Return an array of database names.
286 287 288 |
# File 'lib/mongo/connection.rb', line 286 def database_names database_info.keys end |
#db(db_name, opts = {}) ⇒ Mongo::DB
Return a database with the given name. See DB#new for valid options hash parameters.
299 300 301 |
# File 'lib/mongo/connection.rb', line 299 def db(db_name, opts={}) DB.new(db_name, self, opts) end |
#drop_database(name) ⇒ Object
Drop a database.
317 318 319 |
# File 'lib/mongo/connection.rb', line 317 def drop_database(name) self[name].command(:dropDatabase => 1) end |
#host ⇒ String
The host name used for this connection.
167 168 169 |
# File 'lib/mongo/connection.rb', line 167 def host @primary_pool.host end |
#instrument(name, payload = {}, &blk) ⇒ Object
Execute the block and log the operation described by name and payload. TODO: Not sure if this should take a block.
610 611 612 613 614 |
# File 'lib/mongo/connection.rb', line 610 def instrument(name, payload = {}, &blk) res = yield log_operation(name, payload) res end |
#lock! ⇒ BSON::OrderedHash
Fsync, then lock the mongod process against writes. Use this to get the datafiles in a state safe for snapshotting, backing up, etc.
182 183 184 185 186 187 |
# File 'lib/mongo/connection.rb', line 182 def lock! cmd = BSON::OrderedHash.new cmd[:fsync] = 1 cmd[:lock] = true self['admin'].command(cmd) end |
#locked? ⇒ Boolean
Is this database locked against writes?
192 193 194 |
# File 'lib/mongo/connection.rb', line 192 def locked? self['admin']['$cmd.sys.inprog'].find_one['fsyncLock'] == 1 end |
#logout_pools(db) ⇒ Object
268 269 270 |
# File 'lib/mongo/connection.rb', line 268 def logout_pools(db) @primary_pool.logout_existing(db) end |
#max_bson_size ⇒ Integer
Returns the maximum BSON object size as returned by the core server. Use the 4MB default when the server doesn’t report this.
572 573 574 575 |
# File 'lib/mongo/connection.rb', line 572 def max_bson_size config = self['admin'].command({:ismaster => 1}) config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE end |
#ping ⇒ Hash
Checks if a server is alive. This command will return immediately even if the server is in a lock.
354 355 356 |
# File 'lib/mongo/connection.rb', line 354 def ping self["admin"].command({:ping => 1}) end |
#port ⇒ Integer
The port used for this connection.
174 175 176 |
# File 'lib/mongo/connection.rb', line 174 def port @primary_pool.port end |
#read_primary? ⇒ Boolean Also known as: primary?
Determine whether we’re reading from a primary node. If false, this connection connects to a secondary node and @slave_ok is true.
556 557 558 |
# File 'lib/mongo/connection.rb', line 556 def read_primary? @read_primary end |
#receive_message(operation, message, log_message = nil, socket = nil, command = false) ⇒ Array
Sends a message to the database and waits for the response.
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 |
# File 'lib/mongo/connection.rb', line 471 def (operation, , =nil, socket=nil, command=false) request_id = (, operation) = .to_s begin if socket sock = socket checkin = false else sock = (command ? checkout_writer : checkout_reader) checkin = true end result = '' @safe_mutexes[sock].synchronize do (, sock) result = receive(sock, request_id) end ensure if checkin command ? checkin_writer(sock) : checkin_reader(sock) end end result end |
#remove_auth(db_name) ⇒ Boolean
Remove a saved authentication for this connection.
247 248 249 250 251 252 253 254 |
# File 'lib/mongo/connection.rb', line 247 def remove_auth(db_name) return unless @auths if @auths.reject! { |a| a['db_name'] == db_name } true else false end end |
#send_message(operation, message, opts = {}) ⇒ Integer
Send a message to MongoDB, adding the necessary headers.
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/mongo/connection.rb', line 390 def (operation, , opts={}) if opts.is_a?(String) warn "Connection#send_message no longer takes a string log message. " + "Logging is now handled within the Collection and Cursor classes." opts = {} end connection = opts.fetch(:connection, :writer) begin (, operation) = .to_s if connection == :writer socket = checkout_writer else socket = checkout_reader end (, socket) ensure if connection == :writer checkin_writer(socket) else checkin_reader(socket) end end end |
#send_message_with_safe_check(operation, message, db_name, log_message = nil, last_error_params = false) ⇒ Hash
Sends a message to the database, waits for a response, and raises an exception if the operation has failed.
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/mongo/connection.rb', line 431 def (operation, , db_name, =nil, last_error_params=false) docs = num_received = cursor_id = '' (, operation) = BSON::ByteBuffer.new (, db_name, last_error_params) last_error_id = (, Mongo::Constants::OP_QUERY) = .append!().to_s begin sock = checkout_writer @safe_mutexes[sock].synchronize do (, sock) docs, num_received, cursor_id = receive(sock, last_error_id) end ensure checkin_writer(sock) end if num_received == 1 && (error = docs[0]['err'] || docs[0]['errmsg']) close if error == "not master" error = "wtimeout" if error == "timeout" raise Mongo::OperationFailure, docs[0]['code'].to_s + ': ' + error end docs[0] end |
#server_info ⇒ Hash
Get the build information for the current connection.
361 362 363 |
# File 'lib/mongo/connection.rb', line 361 def server_info self["admin"].command({:buildinfo => 1}) end |
#server_version ⇒ Mongo::ServerVersion
Get the build version of the current server.
370 371 372 |
# File 'lib/mongo/connection.rb', line 370 def server_version ServerVersion.new(server_info["version"]) end |
#slave_ok? ⇒ Boolean
Is it okay to connect to a slave?
377 378 379 |
# File 'lib/mongo/connection.rb', line 377 def slave_ok? @slave_ok end |
#unlock! ⇒ BSON::OrderedHash
Unlock a previously fsync-locked mongod process.
199 200 201 |
# File 'lib/mongo/connection.rb', line 199 def unlock! self['admin']['$cmd.sys.unlock'].find_one end |