Class: Mongo::MongoClient

Inherits:
Object show all
Includes:
Logging, Networking, WriteConcern
Defined in:
lib/mongo/mongo_client.rb

Overview

Instantiates and manages self.connections to MongoDB.

Direct Known Subclasses

Connection, MongoReplicaSetClient

Constant Summary collapse

TCPSocket =
Mongo::TCPSocket
Mutex =
::Mutex
ConditionVariable =
::ConditionVariable
DEFAULT_HOST =
'localhost'
DEFAULT_PORT =
27017
DEFAULT_DB_NAME =
'test'
GENERIC_OPTS =
[:ssl, :auths, :logger, :connect]
TIMEOUT_OPTS =
[:timeout, :op_timeout, :connect_timeout]
POOL_OPTS =
[:pool_size, :pool_timeout]
WRITE_CONCERN_OPTS =
[:w, :j, :fsync, :wtimeout]
CLIENT_ONLY_OPTS =
[:slave_ok]

Constants included from Networking

Networking::RESPONSE_HEADER_SIZE, Networking::STANDARD_HEADER_SIZE

Instance Attribute Summary collapse

Attributes included from WriteConcern

#legacy_write_concern

Class Method Summary collapse

Instance Method Summary collapse

Methods included from WriteConcern

#get_write_concern, gle?, #write_concern_from_legacy

Methods included from Networking

#receive_message, #send_message, #send_message_with_gle

Methods included from Logging

#instrument, instrumenter, instrumenter=, #log, #write_logging_startup_message

Constructor Details

#initialize(host = nil, port = nil, opts = {}) ⇒ MongoClient

Create a connection to single MongoDB instance.

If no args are provided, it will check ENV["MONGODB_URI"].

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 MongoReplicaSetClient.new instead.

Once connected to a replica set, you can find out which nodes are primary, secondary, and arbiters with the corresponding accessors: MongoClient#primary, MongoClient#secondaries, and MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other than the primary.

Examples:

localhost, 27017 (or ENV["MONGODB_URI"] if available)

MongoClient.new

localhost, 27017

MongoClient.new("localhost")

localhost, 3000, max 5 self.connections, with max 5 seconds of wait time.

MongoClient.new("localhost", 3000, :pool_size => 5, :timeout => 5)

localhost, 3000, where this node may be a slave

MongoClient.new("localhost", 3000, :slave_ok => true)

Parameters:

  • host (String, Hash) (defaults to: nil)
  • port (Integer) (defaults to: nil)

    specify a port number here if only one host is being specified.

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

    a customizable set of options

Options Hash (opts):

  • :w (Hash) — default: 1

    , :j (false), :wtimeout (false), :fsync (false) Set the default write concern options propagated to DB objects instantiated off of this MongoClient. This default can be overridden upon instantiation of any DB by explicitly setting an options hash on initialization. It can also be overridden at instantiation of a collection or at the time of a write operation.

  • :slave_ok (Boolean) — default: false

    Must be set to true when connecting to a single, slave node.

  • :logger (Logger, #debug) — default: nil

    A Logger instance for debugging driver ops. Note that logging negatively impacts performance; therefore, it should not be used for high-performance apps.

  • :pool_size (Integer) — default: 1

    The maximum number of socket self.connections allowed per connection pool. Note: this setting is relevant only for multi-threaded applications.

  • :timeout (Float) — default: 5.0

    When all of the self.connections a pool are checked out, this is the number of seconds to wait for a new connection to be released before throwing an exception. Note: this setting is relevant only for multi-threaded applications (which in Ruby are rare).

  • :op_timeout (Float) — default: nil

    The number of seconds to wait for a read operation to time out. Disabled by default.

  • :connect_timeout (Float) — default: nil

    The number of seconds to wait before timing out a connection attempt.

  • :ssl (Boolean) — default: false

    If true, create the connection to the server using SSL.

Raises:

  • (ReplicaSetConnectionError)

    This is raised if a replica set name is specified and the driver fails to connect to a replica set with that name.

  • (MongoArgumentError)

    If called with no arguments and ENV["MONGODB_URI"] implies a replica set.

See Also:



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
# File 'lib/mongo/mongo_client.rb', line 117

def initialize(host=nil, port=nil, opts={})
  if host.nil? and ENV.has_key?('MONGODB_URI')
    parser = URIParser.new ENV['MONGODB_URI']
    if parser.replicaset?
      raise MongoArgumentError, "Mongo::MongoClient.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
    end
    opts.merge!(parser.connection_options)
    @host_to_try = [parser.host, parser.port]
  elsif host.is_a?(String) && (port || DEFAULT_PORT).respond_to?(:to_i)
    @host_to_try = [host, (port || DEFAULT_PORT).to_i]
  elsif host || port
    raise MongoArgumentError, "Mongo::MongoClient.new host or port argument error, host:#{host.inspect}, port:#{port.inspect}"
  else
    @host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
  end

  # Host and port of current master.
  @host = @port = nil

  # Default maximum BSON object size
  @max_bson_size = Mongo::DEFAULT_MAX_BSON_SIZE

  # Lock for request ids.
  @id_lock = Mutex.new

  # Connection pool for primay node
  @primary      = nil
  @primary_pool = nil

  # Not set for direct connection
  @tag_sets = {}
  @acceptable_latency = 15

  check_opts(opts)
  setup(opts)
end

Instance Attribute Details

#acceptable_latencyObject (readonly)

Returns the value of attribute acceptable_latency.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def acceptable_latency
  @acceptable_latency
end

#authsObject (readonly)

Returns the value of attribute auths.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def auths
  @auths
end

#connect_timeoutObject (readonly)

Returns the value of attribute connect_timeout.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def connect_timeout
  @connect_timeout
end

#host_to_tryObject (readonly)

Returns the value of attribute host_to_try.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def host_to_try
  @host_to_try
end

#loggerObject (readonly)

Returns the value of attribute logger.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def logger
  @logger
end

#op_timeoutObject (readonly)

Returns the value of attribute op_timeout.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def op_timeout
  @op_timeout
end

#pool_sizeObject (readonly)

Returns the value of attribute pool_size.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def pool_size
  @pool_size
end

#pool_timeoutObject (readonly)

Returns the value of attribute pool_timeout.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def pool_timeout
  @pool_timeout
end

#primaryObject (readonly)

Returns the value of attribute primary.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def primary
  @primary
end

#primary_poolObject (readonly)

Returns the value of attribute primary_pool.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def primary_pool
  @primary_pool
end

#sizeObject (readonly)

Returns the value of attribute size.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def size
  @size
end

#socket_classObject (readonly)

Returns the value of attribute socket_class.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def socket_class
  @socket_class
end

#tag_setsObject (readonly)

Returns the value of attribute tag_sets.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def tag_sets
  @tag_sets
end

#write_concernObject (readonly)

Returns the value of attribute write_concern.



46
47
48
# File 'lib/mongo/mongo_client.rb', line 46

def write_concern
  @write_concern
end

Class Method Details

.from_uri(uri = , extra_opts = {}) ⇒ Mongo::MongoClient, Mongo::MongoReplicaSetClient

Initialize a connection to MongoDB using the MongoDB URI spec.

Since MongoClient.new cannot be used with any ENV["MONGODB_URI"] that has multiple hosts (implying a replicaset), you may use this when the type of your connection varies by environment and should be determined solely from ENV["MONGODB_URI"].

Parameters:

  • uri (String) (defaults to: )

    A string of the format mongodb://host1[,host2,…[,hostN]][/database]

  • opts

    Any of the options available for MongoClient.new

Returns:



197
198
199
200
# File 'lib/mongo/mongo_client.rb', line 197

def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
  parser = URIParser.new uri
  parser.connection(extra_opts)
end

.multi(nodes, opts = {}) ⇒ Mongo::MongoClient

Deprecated.

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 replaced by the list of canonical nodes returned by running the is_master command on the replica set.

Examples:

Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017]])

This connection will read from a random secondary node.

Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017], ["db3.example.com", 27017]],
                :read_secondary => true)

Parameters:

  • nodes (Array)

    An array of arrays, each of which specifies a host and port.

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

    Any of the available options that can be passed to MongoClient.new.

Options Hash (opts):

  • :rs_name (String) — default: nil

    The name of the replica set to connect to. An exception will be raised if unable to connect to a replica set with this name.

  • :read_secondary (Boolean) — default: false

    When true, this connection object will pick a random slave to send reads to.

Returns:



180
181
182
183
184
# File 'lib/mongo/mongo_client.rb', line 180

def self.multi(nodes, opts={})
  warn "MongoClient.multi is now deprecated and will be removed in v2.0. Please use MongoReplicaSetClient.new instead."

  MongoReplicaSetClient.new(*(nodes+[opts]))
end

Instance Method Details

#[](db_name) ⇒ Mongo::DB

Shortcut for returning a database. Use DB#db to accept options.

Parameters:

  • db_name (String)

    a valid database name.

Returns:



354
355
356
# File 'lib/mongo/mongo_client.rb', line 354

def [](db_name)
  DB.new(db_name, self)
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.

Returns:

  • (Boolean)


475
476
477
478
479
480
481
482
483
# File 'lib/mongo/mongo_client.rb', line 475

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 specified 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 MongoClient#apply_saved_authentication or DB#authenticate.

Parameters:

Returns:

  • (Hash)

    a hash representing the authentication just added.



270
271
272
273
274
275
276
277
278
# File 'lib/mongo/mongo_client.rb', line 270

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.

Returns:

  • (Boolean)

    returns true if authentications exist and succeeds, false if none exists.

Raises:



248
249
250
251
252
253
254
255
# File 'lib/mongo/mongo_client.rb', line 248

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_poolsObject



302
303
304
# File 'lib/mongo/mongo_client.rb', line 302

def authenticate_pools
  @primary_pool.authenticate_existing
end

#checkin(socket) ⇒ Object

Check a socket back into its pool. Note: this is overridden in MongoReplicaSetClient.



541
542
543
544
545
# File 'lib/mongo/mongo_client.rb', line 541

def checkin(socket)
  if @primary_pool && socket && socket.pool
    socket.pool.checkin(socket)
  end
end

#checkout_reader(mode = :primary, tag_sets = {}, acceptable_latency = 15) ⇒ Object

Checkout a socket for reading (i.e., a secondary node). Note: this is overridden in MongoReplicaSetClient.



527
528
529
530
# File 'lib/mongo/mongo_client.rb', line 527

def checkout_reader(mode=:primary, tag_sets={}, acceptable_latency=15)
  connect unless connected?
  @primary_pool.checkout
end

#checkout_writerObject

Checkout a socket for writing (i.e., a primary node). Note: this is overridden in MongoReplicaSetClient.



534
535
536
537
# File 'lib/mongo/mongo_client.rb', line 534

def checkout_writer
  connect unless connected?
  @primary_pool.checkout
end

#clear_authstrue

Remove all authentication information stored in this connection.

Returns:

  • (true)

    this operation return true because it always succeeds.



297
298
299
300
# File 'lib/mongo/mongo_client.rb', line 297

def clear_auths
  @auths = []
  true
end

#closeObject

Close the connection to the database.



511
512
513
514
515
# File 'lib/mongo/mongo_client.rb', line 511

def close
  @primary_pool.close if @primary_pool
  @primary_pool = nil
  @primary = nil
end

#connectObject 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.

Raises:



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/mongo/mongo_client.rb', line 441

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

    @max_bson_size = config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE
    set_primary(@host_to_try)
  end

  if !connected?
    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.

Returns:

  • (Boolean)


465
466
467
# File 'lib/mongo/mongo_client.rb', line 465

def connected?
  @primary_pool && !@primary_pool.closed?
end

#copy_database(from, to, from_host = DEFAULT_HOST, 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.

Parameters:

  • from (String)

    name of the database to copy from.

  • to (String)

    name of the database to copy to.

  • from_host (String) (defaults to: DEFAULT_HOST)

    host of the ‘from’ database.

  • username (String) (defaults to: nil)

    username for authentication against from_db (>=1.3.x).

  • password (String) (defaults to: nil)

    password for authentication against from_db (>=1.3.x).



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/mongo/mongo_client.rb', line 382

def copy_database(from, to, from_host=DEFAULT_HOST, 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_infoHash

Return a hash with all database names and their respective sizes on disk.

Returns:



314
315
316
317
318
319
# File 'lib/mongo/mongo_client.rb', line 314

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_namesArray

Return an array of database names.

Returns:

  • (Array)


324
325
326
# File 'lib/mongo/mongo_client.rb', line 324

def database_names
  database_info.keys
end

#db(db_name = nil, opts = {}) ⇒ Mongo::DB

Return a database with the given name. See DB#new for valid options hash parameters.

Parameters:

  • db_name (String) (defaults to: nil)

    a valid database name.

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

    options to be passed to the DB constructor.

Returns:



337
338
339
340
341
342
343
344
345
# File 'lib/mongo/mongo_client.rb', line 337

def db(db_name=nil, opts={})
  if !db_name && uri = ENV['MONGODB_URI']
    db_name = uri[%r{/([^/\?]+)(\?|$)}, 1]
  end

  db_name ||= DEFAULT_DB_NAME

  DB.new(db_name, self, opts)
end

#drop_database(name) ⇒ Object

Drop a database.

Parameters:

  • name (String)

    name of an existing database.



370
371
372
# File 'lib/mongo/mongo_client.rb', line 370

def drop_database(name)
  self[name].command(:dropDatabase => 1)
end

#hostString

The host name used for this connection.

Returns:



205
206
207
# File 'lib/mongo/mongo_client.rb', line 205

def host
  @primary_pool.host
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.

Returns:

  • (BSON::OrderedHash)

    the command response



220
221
222
223
224
225
# File 'lib/mongo/mongo_client.rb', line 220

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?

Returns:

  • (Boolean)


230
231
232
# File 'lib/mongo/mongo_client.rb', line 230

def locked?
  [1, true].include? self['admin']['$cmd.sys.inprog'].find_one['fsyncLock']
end

#logout_pools(db) ⇒ Object



306
307
308
# File 'lib/mongo/mongo_client.rb', line 306

def logout_pools(db)
  @primary_pool.logout_existing(db)
end

#max_bson_sizeInteger

Returns the maximum BSON object size as returned by the core server. Use the 4MB default when the server doesn’t report this.

Returns:

  • (Integer)


521
522
523
# File 'lib/mongo/mongo_client.rb', line 521

def max_bson_size
  @max_bson_size
end

#pin_pool(pool) ⇒ Object



361
362
# File 'lib/mongo/mongo_client.rb', line 361

def pin_pool(pool)
end

#pingHash

Checks if a server is alive. This command will return immediately even if the server is in a lock.

Returns:



407
408
409
# File 'lib/mongo/mongo_client.rb', line 407

def ping
  self["admin"].command({:ping => 1})
end

#portInteger

The port used for this connection.

Returns:

  • (Integer)


212
213
214
# File 'lib/mongo/mongo_client.rb', line 212

def port
  @primary_pool.port
end

#read_poolMongo::Pool

The socket pool that this connection reads from.

Returns:



497
498
499
# File 'lib/mongo/mongo_client.rb', line 497

def read_pool
  @primary_pool
end

#read_preferenceObject

The value of the read preference.



502
503
504
505
506
507
508
# File 'lib/mongo/mongo_client.rb', line 502

def read_preference
  if slave_ok?
    :secondary_preferred
  else
    :primary
  end
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.

Returns:

  • (Boolean)


489
490
491
# File 'lib/mongo/mongo_client.rb', line 489

def read_primary?
  @read_primary
end

#refreshObject



358
359
# File 'lib/mongo/mongo_client.rb', line 358

def refresh
end

#remove_auth(db_name) ⇒ Boolean

Remove a saved authentication for this connection.

Parameters:

Returns:

  • (Boolean)


285
286
287
288
289
290
291
292
# File 'lib/mongo/mongo_client.rb', line 285

def remove_auth(db_name)
  return unless @auths
  if @auths.reject! { |a| a['db_name'] == db_name }
    true
  else
    false
  end
end

#server_infoHash

Get the build information for the current connection.

Returns:



414
415
416
# File 'lib/mongo/mongo_client.rb', line 414

def server_info
  self["admin"].command({:buildinfo => 1})
end

#server_versionMongo::ServerVersion

Get the build version of the current server.

Returns:



423
424
425
# File 'lib/mongo/mongo_client.rb', line 423

def server_version
  ServerVersion.new(server_info["version"])
end

#slave_ok?Boolean

Is it okay to connect to a slave?

Returns:

  • (Boolean)


430
431
432
# File 'lib/mongo/mongo_client.rb', line 430

def slave_ok?
  @slave_ok
end

#unlock!BSON::OrderedHash

Unlock a previously fsync-locked mongod process.

Returns:

  • (BSON::OrderedHash)

    command response



237
238
239
# File 'lib/mongo/mongo_client.rb', line 237

def unlock!
  self['admin']['$cmd.sys.unlock'].find_one
end

#unpin_pool(pool) ⇒ Object



364
365
# File 'lib/mongo/mongo_client.rb', line 364

def unpin_pool(pool)
end