class Mongo::Cluster::Topology::ReplicaSet

Defines behaviour when a cluster is in replica set topology.

@since 2.0.0

Constants

NAME

The display name for the topology.

@since 2.0.0

REPLICA_SET_NAME

Constant for the replica set name configuration option.

@since 2.0.0

Attributes

monitoring[R]

@return [ Monitoring ] monitoring The monitoring.

options[R]

@return [ Hash ] options The options.

Public Class Methods

new(options, monitoring, seeds = []) click to toggle source

Initialize the topology with the options.

@example Initialize the topology.

ReplicaSet.new(options)

@param [ Hash ] options The options. @param [ Monitoring ] monitoring The monitoring. @param [ Array<String> ] seeds The seeds.

@option options [ Symbol ] :replica_set Name of the replica set to

connect to. Can be left blank (either nil or the empty string are
accepted) to discover the name from the seeds. If the seeds
belong to different replica sets there is no guarantee which
replica set is selected - in particular, the driver may choose
the replica set name of a secondary if it returns its response
prior to a primary belonging to a different replica set.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 135
def initialize(options, monitoring, seeds = [])
  @options = options
  @monitoring = monitoring
  @max_election_id = nil
  @max_set_version = nil
end

Public Instance Methods

add_hosts?(description, servers) click to toggle source

Whether a server description's hosts may be added to the cluster.

@example Check if a description's hosts may be added to the cluster.

topology.add_hosts?(description, servers)

@param [ Mongo::Server::Description ] description The description. @param [ Array<Mongo::Server> ] servers The cluster servers.

@return [ true, false ] Whether a description's hosts may be added.

@since 2.0.6

# File lib/mongo/cluster/topology/replica_set.rb, line 192
def add_hosts?(description, servers)
  !!(member_of_this_set?(description) &&
      (!has_primary?(servers) || description.primary?))
end
display_name() click to toggle source

Get the display name.

@example Get the display name.

ReplicaSet.display_name

@return [ String ] The display name.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 50
def display_name
  NAME
end
elect_primary(description, servers) click to toggle source

Elect a primary server within this topology.

@example Elect a primary server.

topology.elect_primary(description, servers)

@param [ Server::Description ] description The description of the

elected primary.

@param [ Array<Server> ] servers The list of known servers to the

cluster.

@return [ ReplicaSet ] The topology.

# File lib/mongo/cluster/topology/replica_set.rb, line 65
def elect_primary(description, servers)
  if description.replica_set_name == replica_set_name
    unless detect_stale_primary!(description)
      servers.each do |server|
        if server.primary? && server.address != description.address
          server.description.unknown!
        end
      end
      update_max_election_id(description)
      update_max_set_version(description)
    end
  else
    log_warn(
      "Server #{description.address.to_s} has incorrect replica set name: " +
      "'#{description.replica_set_name}'. The current replica set name is '#{replica_set_name}'."
    )
  end
  self
end
has_readable_server?(cluster, server_selector = nil) click to toggle source

Determine if the topology would select a readable server for the provided candidates and read preference.

@example Is a readable server present?

topology.has_readable_server?(cluster, server_selector)

@param [ Cluster ] cluster The cluster. @param [ ServerSelector ] server_selector The server

selector.

@return [ true, false ] If a readable server is present.

@since 2.4.0

# File lib/mongo/cluster/topology/replica_set.rb, line 98
def has_readable_server?(cluster, server_selector = nil)
  (server_selector || ServerSelector.get(mode: :primary)).candidates(cluster).any?
end
has_writable_server?(cluster) click to toggle source

Determine if the topology would select a writable server for the provided candidates.

@example Is a writable server present?

topology.has_writable_server?(servers)

@param [ Cluster ] cluster The cluster.

@return [ true, false ] If a writable server is present.

@since 2.4.0

# File lib/mongo/cluster/topology/replica_set.rb, line 113
def has_writable_server?(cluster)
  cluster.servers.any?{ |server| server.primary? }
end
member_discovered() click to toggle source

Notify the topology that a member was discovered.

@example Notify the topology that a member was discovered.

topology.member_discovered

@since 2.4.0

# File lib/mongo/cluster/topology/replica_set.rb, line 287
def member_discovered; end
remove_hosts?(description) click to toggle source

Whether a description can be used to remove hosts from the cluster.

@example Check if a description can be used to remove hosts from the cluster.

topology.remove_hosts?(description)

@param [ Mongo::Server::Description ] description The description.

@return [ true, false ] Whether hosts may be removed from the cluster.

@since 2.0.6

# File lib/mongo/cluster/topology/replica_set.rb, line 207
def remove_hosts?(description)
  !description.config.empty? &&
    (description.primary? ||
      description.me_mismatch? ||
        description.hosts.empty? ||
          !member_of_this_set?(description))
end
remove_server?(description, server) click to toggle source

Whether a specific server in the cluster can be removed, given a description. As described in the SDAM spec, a server should be removed if the server's address does not match the “me” field of the isMaster response, if the server has a different replica set name, or if an isMaster response from the primary does not contain the server's address in the list of known hosts. Note that as described by the spec, a server determined to be of type Unknown from its isMaster response is NOT removed from the topology.

@example Check if a specific server can be removed from the cluster.

topology.remove_server?(description, server)

@param [ Mongo::Server::Description ] description The description. @param [ Mongo::Serve ] server The server in question.

@return [ true, false ] Whether the server can be removed from the cluster.

@since 2.0.6

# File lib/mongo/cluster/topology/replica_set.rb, line 232
def remove_server?(description, server)
  ((server.address == description.address) && description.me_mismatch?) ||
  remove_self?(description, server) ||
    (member_of_this_set?(description) &&
        description.server_type == :primary &&
        !description.servers.empty? &&
          !description.lists_server?(server))
end
replica_set?() click to toggle source

A replica set topology is a replica set.

@example Is the topology a replica set?

ReplicaSet.replica_set?

@return [ true ] Always true.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 150
def replica_set?; true; end
replica_set_name() click to toggle source

Get the replica set name configured for this topology.

@example Get the replica set name.

topology.replica_set_name

@return [ String ] The name of the configured replica set.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 160
def replica_set_name
  @replica_set_name ||= options[REPLICA_SET_NAME]
end
servers(servers) click to toggle source

Select appropriate servers for this topology.

@example Select the servers.

ReplicaSet.servers(servers)

@param [ Array<Server> ] servers The known servers.

@return [ Array<Server> ] The servers in the replica set.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 174
def servers(servers)
  servers.select do |server|
    (replica_set_name.nil? || server.replica_set_name == replica_set_name) &&
      server.primary? || server.secondary?
  end
end
sharded?() click to toggle source

A replica set topology is not sharded.

@example Is the topology sharded?

ReplicaSet.sharded?

@return [ false ] Always false.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 249
def sharded?; false; end
single?() click to toggle source

A replica set topology is not single.

@example Is the topology single?

ReplicaSet.single?

@return [ false ] Always false.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 259
def single?; false; end
standalone_discovered() click to toggle source

Notify the topology that a standalone was discovered.

@example Notify the topology that a standalone was discovered.

topology.standalone_discovered

@return [ Topology::ReplicaSet ] Always returns self.

@since 2.0.6

# File lib/mongo/cluster/topology/replica_set.rb, line 279
def standalone_discovered; self; end
unknown?() click to toggle source

A replica set topology is not unknown.

@example Is the topology unknown?

ReplicaSet.unknown?

@return [ false ] Always false.

@since 2.0.0

# File lib/mongo/cluster/topology/replica_set.rb, line 269
def unknown?; false; end

Private Instance Methods

detect_stale_primary!(description) click to toggle source
# File lib/mongo/cluster/topology/replica_set.rb, line 307
def detect_stale_primary!(description)
  if description.election_id && description.set_version
    if @max_set_version && @max_election_id &&
        (description.set_version < @max_set_version ||
            (description.set_version == @max_set_version &&
                description.election_id < @max_election_id))
      description.unknown!
    end
  end
end
has_primary?(servers) click to toggle source
# File lib/mongo/cluster/topology/replica_set.rb, line 318
def has_primary?(servers)
  servers.find { |s| s.primary? }
end
member_of_this_set?(description) click to toggle source
# File lib/mongo/cluster/topology/replica_set.rb, line 322
def member_of_this_set?(description)
  description.replica_set_member? &&
    description.replica_set_name == replica_set_name
end
remove_self?(description, server) click to toggle source

As described by the SDAM spec, a server should be removed from the topology upon receiving its isMaster response if no error occurred and replica set name does not match that of the topology.

# File lib/mongo/cluster/topology/replica_set.rb, line 330
def remove_self?(description, server)
  !description.unknown? &&
    !member_of_this_set?(description) &&
      description.is_server?(server) &&
        !description.ghost?
end
update_max_election_id(description) click to toggle source
# File lib/mongo/cluster/topology/replica_set.rb, line 291
def update_max_election_id(description)
  if description.election_id &&
      (@max_election_id.nil? ||
          description.election_id > @max_election_id)
    @max_election_id = description.election_id
  end
end
update_max_set_version(description) click to toggle source
# File lib/mongo/cluster/topology/replica_set.rb, line 299
def update_max_set_version(description)
  if description.set_version &&
      (@max_set_version.nil? ||
          description.set_version > @max_set_version)
    @max_set_version = description.set_version
  end
end