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

Mutex =
::Mutex
ConditionVariable =
::ConditionVariable
DEFAULT_HOST =
'localhost'
DEFAULT_PORT =
27017
DEFAULT_DB_NAME =
'test'
GENERIC_OPTS =
[:auths, :logger, :connect, :default_db]
TIMEOUT_OPTS =
[:timeout, :op_timeout, :connect_timeout]
SSL_OPTS =
[:ssl, :ssl_key, :ssl_cert, :ssl_verify, :ssl_ca_cert]
POOL_OPTS =
[:pool_size, :pool_timeout]
READ_PREFERENCE_OPTS =
[:read, :tag_sets, :secondary_acceptable_latency_ms]
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, port, 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, :pool_timeout => 5)

localhost, 3000, where this node may be a slave

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

Unix Domain Socket

MongoClient.new("/var/run/mongodb.sock")

Notes about Write-Concern Options:

Write concern options are propagated to objects instantiated from this MongoClient.
These defaults can be overridden upon instantiation of any object by explicitly setting an options hash
on initialization.

Parameters:

  • host (String)

    hostname for the target MongoDB server.

  • port (Integer)

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

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

    hash of optional settings and configuration values.

Options Hash (opts):

  • :w (String, Integer, Symbol) — default: 1

    Set default number of nodes to which a write should be acknowledged

  • :j (Boolean) — default: false

    Set journal acknowledgement

  • :wtimeout (Integer) — default: nil

    Set replica set acknowledgement timeout

  • :fsync (Boolean) — default: false

    Set fsync acknowledgement.

  • :ssl (Boolean) — default: false

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

  • :ssl_cert (String) — default: nil

    The certificate file used to identify the local connection against MongoDB.

  • :ssl_key (String) — default: nil

    The private keyfile used to identify the local connection against MongoDB. If included with the :ssl_cert then only :ssl_cert is needed.

  • :ssl_verify (Boolean) — default: nil

    Specifies whether or not peer certification validation should occur.

  • :ssl_ca_cert (String) — default: nil

    The ca_certs file contains a set of concatenated “certification authority” certificates, which are used to validate certificates passed from the other end of the connection. Required for :ssl_verify.

  • :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.

  • :pool_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.

  • :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.

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:



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/mongo/mongo_client.rb', line 135

def initialize(*args)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  @host, @port = parse_init(args[0], args[1], opts)

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

  # Connection pool for primary node
  @primary      = nil
  @primary_pool = nil
  @mongos       = false

  # Not set for direct connection
  @tag_sets = []
  @acceptable_latency = 15

  @max_message_size = nil
  @max_bson_size = nil

  check_opts(opts)
  setup(opts.dup)
end

Instance Attribute Details

#acceptable_latencyObject (readonly)

Returns the value of attribute acceptable_latency.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def acceptable_latency
  @acceptable_latency
end

#authsObject (readonly)

Returns the value of attribute auths.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def auths
  @auths
end

#connect_timeoutObject (readonly)

Returns the value of attribute connect_timeout.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def connect_timeout
  @connect_timeout
end

#host_to_tryObject (readonly)

Returns the value of attribute host_to_try.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def host_to_try
  @host_to_try
end

#loggerObject (readonly)

Returns the value of attribute logger.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def logger
  @logger
end

#op_timeoutObject (readonly)

Returns the value of attribute op_timeout.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def op_timeout
  @op_timeout
end

#pool_sizeObject (readonly)

Returns the value of attribute pool_size.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def pool_size
  @pool_size
end

#pool_timeoutObject (readonly)

Returns the value of attribute pool_timeout.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def pool_timeout
  @pool_timeout
end

#primaryObject (readonly)

Returns the value of attribute primary.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def primary
  @primary
end

#primary_poolObject (readonly)

Returns the value of attribute primary_pool.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def primary_pool
  @primary_pool
end

#readObject (readonly)

Returns the value of attribute read.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def read
  @read
end

#sizeObject (readonly)

Returns the value of attribute size.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def size
  @size
end

#socket_classObject (readonly)

Returns the value of attribute socket_class.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def socket_class
  @socket_class
end

#socket_optsObject (readonly)

Returns the value of attribute socket_opts.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def socket_opts
  @socket_opts
end

#tag_setsObject (readonly)

Returns the value of attribute tag_sets.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

def tag_sets
  @tag_sets
end

#write_concernObject (readonly)

Returns the value of attribute write_concern.



43
44
45
# File 'lib/mongo/mongo_client.rb', line 43

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:



201
202
203
204
# File 'lib/mongo/mongo_client.rb', line 201

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:



184
185
186
187
188
# File 'lib/mongo/mongo_client.rb', line 184

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:



372
373
374
# File 'lib/mongo/mongo_client.rb', line 372

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)


505
506
507
508
509
510
511
512
513
# File 'lib/mongo/mongo_client.rb', line 505

def active?
  return false unless connected?

  ping
  true

  rescue ConnectionFailure
  false
end

#add_auth(db_name, username, password, source) ⇒ 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.



292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/mongo/mongo_client.rb', line 292

def add_auth(db_name, username, password, source)
  if @auths.any? {|a| a[:db_name] == db_name}
    raise MongoArgumentError, "Cannot apply multiple authentications to database '#{db_name}'"
  end

  auth = {
    :db_name  => db_name,
    :username => username,
    :password => password,
    :source => source
  }
  @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:



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

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,
      :source => auth[:source], :socket => opts[:socket])
  end
  true
end

#authenticate_poolsObject



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

def authenticate_pools
  @primary_pool.authenticate_existing
end

#check_is_master(node) ⇒ Hash

Internal method for checking isMaster() on a given node.

Parameters:

  • node (Array)

    Port and host for the target node

Returns:

  • (Hash)

    Response from isMaster()



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
# File 'lib/mongo/mongo_client.rb', line 578

def check_is_master(node)
  begin
    host, port = *node
    config = nil
    socket = @socket_class.new(host, port, @op_timeout, @connect_timeout, @socket_opts)
    if @connect_timeout
      Timeout::timeout(@connect_timeout, OperationTimeout) do
        config = self['admin'].command({:ismaster => 1}, :socket => socket)
      end
    else
      config = self['admin'].command({:ismaster => 1}, :socket => socket)
    end
  rescue OperationFailure, SocketError, SystemCallError, IOError
    close
  ensure
    socket.close unless socket.nil? || socket.closed?
  end
  config
end

#checkin(socket) ⇒ Object

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



566
567
568
569
570
# File 'lib/mongo/mongo_client.rb', line 566

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

#checkout_reader(read_preference) ⇒ Object

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



552
553
554
555
# File 'lib/mongo/mongo_client.rb', line 552

def checkout_reader(read_preference)
  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.



559
560
561
562
# File 'lib/mongo/mongo_client.rb', line 559

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.



320
321
322
323
# File 'lib/mongo/mongo_client.rb', line 320

def clear_auths
  @auths = []
  true
end

#closeObject

Close the connection to the database.



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

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:



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/mongo/mongo_client.rb', line 466

def connect
  close
  config = check_is_master(host_port)
  if config
    if config['ismaster'] == 1 || config['ismaster'] == true
      @read_primary = true
    elsif @slave_ok
      @read_primary = false
    end

    if config.has_key?('msg') && config['msg'] == 'isdbgrid'
      @mongos = true
    end

    @max_bson_size = config['maxBsonObjectSize']
    @max_message_size = config['maxMessageSizeBytes']
    set_primary(host_port)
  end

  if !connected?
    raise ConnectionFailure, "Failed to connect to a master node at #{host_port.join(":")}"
  end
  true
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)


495
496
497
# File 'lib/mongo/mongo_client.rb', line 495

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).



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/mongo/mongo_client.rb', line 404

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:



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

def database_info
  doc = self['admin'].command({:listDatabases => 1})
  doc['databases'].inject({}) do |info, db|
    info[db['name']] = db['sizeOnDisk'].to_i
    info
  end
end

#database_namesArray

Return an array of database names.

Returns:

  • (Array)


348
349
350
# File 'lib/mongo/mongo_client.rb', line 348

def database_names
  database_info.keys
end

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

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

Parameters:

  • db_name (String) (defaults to: @default_db)

    a valid database name.

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

    options to be passed to the DB constructor.

Returns:



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

def db(db_name = @default_db, opts = {})
  DB.new(db_name, self, opts)
end

#drop_database(name) ⇒ Object

Drop a database.

Parameters:

  • name (String)

    name of an existing database.



392
393
394
# File 'lib/mongo/mongo_client.rb', line 392

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

#hostString

The host name used for this connection.

Returns:



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

def host
  @primary_pool.host
end

#host_portObject



234
235
236
# File 'lib/mongo/mongo_client.rb', line 234

def host_port
  [@host, @port]
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



242
243
244
245
246
247
# File 'lib/mongo/mongo_client.rb', line 242

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)


252
253
254
# File 'lib/mongo/mongo_client.rb', line 252

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

#logout_pools(db) ⇒ Object



329
330
331
# File 'lib/mongo/mongo_client.rb', line 329

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)


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

def max_bson_size
  @max_bson_size || DEFAULT_MAX_BSON_SIZE
end

#max_message_sizeObject



546
547
548
# File 'lib/mongo/mongo_client.rb', line 546

def max_message_size
  @max_message_size || max_bson_size * MESSAGE_SIZE_FACTOR
end

#mongos?Boolean

Returns:

  • (Boolean)


455
456
457
# File 'lib/mongo/mongo_client.rb', line 455

def mongos?
  @mongos
end

#parse_init(host, port, opts) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/mongo/mongo_client.rb', line 206

def parse_init(host, port, opts)
  if host.nil? && port.nil? && ENV.has_key?('MONGODB_URI')
    parser = URIParser.new(ENV['MONGODB_URI'])
    if parser.replicaset?
      raise MongoArgumentError,
        "ENV['MONGODB_URI'] implies a replica set."
    end
    opts.merge!(parser.connection_options)
    [parser.host, parser.port]
  else
    [host || DEFAULT_HOST, port || DEFAULT_PORT]
  end
end

#pin_pool(pool, read_prefs) ⇒ Object



383
384
# File 'lib/mongo/mongo_client.rb', line 383

def pin_pool(pool, read_prefs)
end

#pingHash

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

Returns:



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

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

#pinned_poolObject



379
380
381
# File 'lib/mongo/mongo_client.rb', line 379

def pinned_pool
  @primary_pool
end

#portInteger

The port used for this connection.

Returns:

  • (Integer)


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

def port
  @primary_pool.port
end

#read_poolMongo::Pool

The socket pool that this connection reads from.

Returns:



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

def read_pool
  @primary_pool
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)


519
520
521
# File 'lib/mongo/mongo_client.rb', line 519

def read_primary?
  @read_primary
end

#refreshObject



376
377
# File 'lib/mongo/mongo_client.rb', line 376

def refresh
end

#remove_auth(db_name) ⇒ Boolean

Remove a saved authentication for this connection.

Parameters:

Returns:

  • (Boolean)


312
313
314
315
# File 'lib/mongo/mongo_client.rb', line 312

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

#server_infoHash

Get the build information for the current connection.

Returns:



436
437
438
# File 'lib/mongo/mongo_client.rb', line 436

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

#server_versionMongo::ServerVersion

Get the build version of the current server.

Returns:



444
445
446
# File 'lib/mongo/mongo_client.rb', line 444

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

#slave_ok?Boolean

Is it okay to connect to a slave?

Returns:

  • (Boolean)


451
452
453
# File 'lib/mongo/mongo_client.rb', line 451

def slave_ok?
  @slave_ok
end

#unlock!BSON::OrderedHash

Unlock a previously fsync-locked mongod process.

Returns:

  • (BSON::OrderedHash)

    command response



259
260
261
# File 'lib/mongo/mongo_client.rb', line 259

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

#unpin_poolObject



386
387
# File 'lib/mongo/mongo_client.rb', line 386

def unpin_pool
end