Class Mongo::ReplSetConnection
In: lib/mongo/repl_set_connection.rb
Parent: Connection

Instantiates and manages connections to a MongoDB replica set.

Methods

Attributes

arbiters  [R] 
nodes  [R] 
read_pool  [R] 
refresh_interval  [R] 
refresh_mode  [R] 
replica_set_name  [R] 
secondaries  [R] 
secondary_pools  [R] 
seeds  [R] 
tags_to_pools  [R] 

Public Class methods

Create a connection to a MongoDB replica set.

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.

@param [Array] args A list of host-port pairs to be used as seed nodes followed by a

  hash containing any options. See the examples below for exactly how to use the constructor.

@option options [String] :rs_name (nil) The name of the replica set to connect to. You

  can use this option to verify that you're connecting to the right replica set.

@option options [Boolean, Hash] :safe (false) Set the default safe-mode options

  propogated to DB objects instantiated off of this Connection. This
  default can be overridden upon instantiation of any DB by explicity setting a :safe value
  on initialization.

@option options [:primary, :secondary] :read (:primary) The default read preference for Mongo::DB

  objects created from this connection object. If +:secondary+ is chosen, reads will be sent
  to one of the closest available secondary nodes. If a secondary node cannot be located, the
  read will be sent to the primary.

@option options [Logger] :logger (nil) Logger instance to receive driver operation log. @option options [Integer] :pool_size (1) The maximum number of socket connections allowed per

  connection pool. Note: this setting is relevant only for multi-threaded applications.

@option options [Float] :pool_timeout (5.0) When all of the 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.

@option opts [Float] :op_timeout (nil) The number of seconds to wait for a read operation to time out.

  Disabled by default.

@option opts [Float] :connect_timeout (nil) The number of seconds to wait before timing out a

  connection attempt.

@option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL. @option opts [Boolean] :refresh_mode (:sync) Set this to :async to enable a background thread that

  periodically updates the state of the connection. If, for example, you initially connect while a secondary
  is down, this will reconnect to that secondary behind the scenes to
  prevent you from having to reconnect manually. If set to :sync, refresh will happen
  synchronously. If +false+, no automatic refresh will occur unless there's a connection failure.

@option opts [Integer] :refresh_interval (90) If :refresh_mode is enabled, this is the number of seconds

  between calls to check the replica set's state.

@option opts [Boolean] :require_primary (true) If true, require a primary node for the connection

  to succeed. Otherwise, connection will succeed as long as there's at least one secondary node.

@example Connect to a replica set and provide two seed nodes. Note that the number of seed nodes does

  not have to be equal to the number of replica set members. The purpose of seed nodes is to permit
  the driver to find at least one replica set member even if a member is down.
  ReplSetConnection.new(['localhost', 30000], ['localhost', 30001])

@example Connect to a replica set providing two seed nodes and ensuring a connection to the replica set named ‘prod’:

  ReplSetConnection.new(['localhost', 30000], ['localhost', 30001], :rs_name => 'prod')

@example Connect to a replica set providing two seed nodes and allowing reads from a secondary node:

  ReplSetConnection.new(['localhost', 30000], ['localhost', 30001], :read_secondary => true)

@see api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby

@raise [ReplicaSetConnectionError] This is raised if a replica set name is specified and the

  driver fails to connect to a replica set with that name.

[Source]

# File lib/mongo/repl_set_connection.rb, line 85
    def initialize(*args)
      extend Sync_m

      if args.last.is_a?(Hash)
        opts = args.pop
      else
        opts = {}
      end

      unless args.length > 0
        raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
      end

      # The list of seed nodes
      @seeds = args

      # TODO: get rid of this
      @nodes = @seeds.dup

      # The members of the replica set, stored as instances of Mongo::Node.
      @members = []

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

      # Connection pools for each secondary node
      @secondaries = []
      @secondary_pools = []

      # The secondary pool to which we'll be sending reads.
      # This may be identical to the primary pool.
      @read_pool = nil

      # A list of arbiter addresses (for client information only)
      @arbiters = []

      # Refresh
      @refresh_mode = opts.fetch(:refresh_mode, :sync)
      @refresh_interval = opts[:refresh_interval] || 90

      if ![:sync, :async, false].include?(@refresh_mode)
        raise MongoArgumentError,
          "Refresh mode must be one of :sync, :async, or false."
      end

      # Are we allowing reads from secondaries?
      if opts[:read_secondary]
        warn ":read_secondary options has now been deprecated and will " +
          "be removed in driver v2.0. Use the :read option instead."
        @read_secondary = opts.fetch(:read_secondary, false)
        @read = :secondary
      else
        @read = opts.fetch(:read, :primary)
        Mongo::Support.validate_read_preference(@read)
      end

      @connected = false

      # Store the refresher thread
      @refresh_thread = nil

      # Maps
      @sockets_to_pools = {}
      @tags_to_pools = {}

      # Replica set name
      if opts[:rs_name]
        warn ":rs_name option has been deprecated and will be removed in v2.0. " +
          "Please use :name instead."
        @replica_set_name = opts[:rs_name]
      else
        @replica_set_name = opts[:name]
      end

      # Require a primary node to connect?
      @require_primary = opts.fetch(:require_primary, true)

      setup(opts)
    end

Public Instance methods

[Source]

# File lib/mongo/repl_set_connection.rb, line 326
    def authenticate_pools
      super
      @secondary_pools.each do |pool|
        pool.authenticate_existing
      end
    end

Close the connection to the database.

[Source]

# File lib/mongo/repl_set_connection.rb, line 273
    def close
      sync_synchronize(:EX) do
        @connected = false
        super

        if @refresh_thread
          @refresh_thread.kill
          @refresh_thread = nil
        end

        if @nodes
          @nodes.each do |member|
            member.close
          end
        end

        @nodes = []
        @read_pool = nil

        if @secondary_pools
          @secondary_pools.each do |pool|
            pool.close
          end
        end

        @secondaries     = []
        @secondary_pools = []
        @arbiters        = []
        @tags_to_pools.clear
        @sockets_to_pools.clear
      end
    end

Initiate a connection to the replica set.

[Source]

# File lib/mongo/repl_set_connection.rb, line 172
    def connect
      log(:info, "Connecting...")
      sync_synchronize(:EX) do
        return if @connected
        manager = PoolManager.new(self, @seeds)
        manager.connect

        update_config(manager)
        initiate_refresh_mode

        if @require_primary && @primary.nil? #TODO: in v2.0, we'll let this be optional and do a lazy connect.
          raise ConnectionFailure, "Failed to connect to primary node."
        elsif !@read_pool
          raise ConnectionFailure, "Failed to connect to any node."
        else
          @connected = true
        end
      end
    end

[Source]

# File lib/mongo/repl_set_connection.rb, line 227
    def connected?
      !@primary_pool.nil? || !@read_pool.nil?
    end

@deprecated

[Source]

# File lib/mongo/repl_set_connection.rb, line 232
    def connecting?
      warn "ReplSetConnection#connecting? is deprecated and will be removed in v2.0."
      false
    end

The replica set primary‘s host name.

@return [String]

[Source]

# File lib/mongo/repl_set_connection.rb, line 240
    def host
      super
    end

[Source]

# File lib/mongo/repl_set_connection.rb, line 166
    def inspect
      "<Mongo::ReplSetConnection:0x#{self.object_id.to_s(16)} @seeds=#{@seeds} " +
        "@connected=#{@connected}>"
    end

[Source]

# File lib/mongo/repl_set_connection.rb, line 333
    def logout_pools(db)
      super
      @secondary_pools.each do |pool|
        pool.logout_existing(db)
      end
    end

[Source]

# File lib/mongo/repl_set_connection.rb, line 251
    def nodes
      warn "ReplSetConnection#nodes is DEPRECATED and will be removed in v2.0. " +
        "Please use ReplSetConnection#seeds instead."
      @seeds
    end

The replica set primary‘s port.

@return [Integer]

[Source]

# File lib/mongo/repl_set_connection.rb, line 247
    def port
      super
    end
primary?()

Alias for read_primary?

[Source]

# File lib/mongo/repl_set_connection.rb, line 268
    def read_preference
      @read
    end

Determine whether we‘re reading from a primary node. If false, this connection connects to a secondary node and @read_secondaries is true.

@return [Boolean]

[Source]

# File lib/mongo/repl_set_connection.rb, line 261
    def read_primary?
      sync_synchronize(:SH) do
        @read_pool == @primary_pool
      end
    end

Refresh the current replica set configuration.

[Source]

# File lib/mongo/repl_set_connection.rb, line 211
    def refresh(opts={})
      return false if !connected?

      # Return if another thread is already in the process of refreshing.
      return if sync_exclusive?

      sync_synchronize(:EX) do
        log(:info, "Refreshing...")
        @background_manager ||= PoolManager.new(self, @seeds)
        @background_manager.connect
        update_config(@background_manager)
      end

      return true
    end

If a ConnectionFailure is raised, this method will be called to close the connection and reset connection values. @deprecated

[Source]

# File lib/mongo/repl_set_connection.rb, line 309
    def reset_connection
      close
      warn "ReplSetConnection#reset_connection is now deprecated and will be removed in v2.0. " +
        "Use ReplSetConnection#close instead."
    end

Returns true if it‘s okay to read from a secondary node. Since this is a replica set, this must always be true.

This method exist primarily so that Cursor objects will generate query messages with a slaveOkay value of true.

@return [Boolean] true

[Source]

# File lib/mongo/repl_set_connection.rb, line 322
    def slave_ok?
      true
    end

Note: this method must be called from within an exclusive lock.

[Source]

# File lib/mongo/repl_set_connection.rb, line 194
    def update_config(manager)
      @arbiters = manager.arbiters.nil? ? [] : manager.arbiters.dup
      @primary = manager.primary.nil? ? nil : manager.primary.dup
      @secondaries = manager.secondaries.dup
      @hosts = manager.hosts.dup

      @primary_pool = manager.primary_pool
      @read_pool    = manager.read_pool
      @secondary_pools = manager.secondary_pools
      @tags_to_pools   = manager.tags_to_pools
      @seeds = manager.seeds
      @manager = manager
      @nodes = manager.nodes
      @max_bson_size = manager.max_bson_size
    end

[Validate]