class Mongo::Node

Attributes

address[RW]
client[RW]
host[RW]
last_state[RW]
port[RW]
socket[RW]

Public Class Methods

new(client, host_port) click to toggle source
# File lib/mongo/connection/node.rb, line 20
def initialize(client, host_port)
  @client = client
  @manager = @client.local_manager
  @host, @port = Support.normalize_seeds(host_port)
  @address = "#{@host}:#{@port}"
  @config = nil
  @socket = nil
  @node_mutex = Monitor.new
end

Public Instance Methods

==(other)
Alias for: eql?
=~(other) click to toggle source
# File lib/mongo/connection/node.rb, line 35
def =~(other)
  if other.is_a?(String)
    h, p = Support.normalize_seeds(other)
    h == @host && p == @port
  else
    false
  end
end
active?() click to toggle source
# File lib/mongo/connection/node.rb, line 89
def active?
  begin
    result = @client['admin'].command({:ping => 1}, :socket => usable_socket)
  rescue OperationFailure, SocketError, SystemCallError, IOError
    return nil
  end
  result['ok'] == 1
end
arbiters() click to toggle source
# File lib/mongo/connection/node.rb, line 145
def arbiters
  return [] unless config['arbiters']
  config['arbiters'].map do |arbiter|
    Support.normalize_seeds(arbiter)
  end
end
close() click to toggle source

This should only be called within a mutex

# File lib/mongo/connection/node.rb, line 77
def close
  if @socket && !@socket.closed?
    @socket.close
  end
  @socket = nil
  @config = nil
end
config() click to toggle source
# File lib/mongo/connection/node.rb, line 48
def config
  connect unless connected?
  set_config unless @config || !connected?
  @config
end
connect() click to toggle source

Create a connection to the provided node, and, if successful, return the socket. Otherwise, return nil.

# File lib/mongo/connection/node.rb, line 61
def connect
  @node_mutex.synchronize do
    begin
      @socket = @client.socket_class.new(@host, @port,
                                         @client.op_timeout,
                                         @client.connect_timeout,
                                         @client.socket_opts)
    rescue ConnectionTimeoutError, OperationTimeout, ConnectionFailure, OperationFailure,
           SocketError, SystemCallError, IOError => ex
      @client.log(:debug, "Failed connection to #{host_string} with #{ex.class}, #{ex.message}.")
      close
    end
  end
end
connected?() click to toggle source
# File lib/mongo/connection/node.rb, line 85
def connected?
  @socket != nil && !@socket.closed?
end
eql?(other) click to toggle source
# File lib/mongo/connection/node.rb, line 30
def eql?(other)
  (other.is_a?(Node) && @address == other.address)
end
Also aliased as: ==
hash() click to toggle source
# File lib/mongo/connection/node.rb, line 168
def hash
  address.hash
end
healthy?() click to toggle source
# File lib/mongo/connection/node.rb, line 172
def healthy?
  connected? && config
end
host_port() click to toggle source
# File lib/mongo/connection/node.rb, line 164
def host_port
  [@host, @port]
end
host_string() click to toggle source
# File lib/mongo/connection/node.rb, line 44
def host_string
  address
end
inspect() click to toggle source
# File lib/mongo/connection/node.rb, line 54
def inspect
  "<Mongo::Node:0x#{self.object_id.to_s(16)} @host=#{@host} @port=#{@port}>"
end
max_bson_size() click to toggle source
# File lib/mongo/connection/node.rb, line 176
def max_bson_size
  @max_bson_size || DEFAULT_MAX_BSON_SIZE
end
max_message_size() click to toggle source
# File lib/mongo/connection/node.rb, line 180
def max_message_size
  @max_message_size || max_bson_size * MESSAGE_SIZE_FACTOR
end
max_wire_version() click to toggle source
# File lib/mongo/connection/node.rb, line 184
def max_wire_version
  @max_wire_version || 0
end
max_write_batch_size() click to toggle source
# File lib/mongo/connection/node.rb, line 196
def max_write_batch_size
  @max_write_batch_size || Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE
end
min_wire_version() click to toggle source
# File lib/mongo/connection/node.rb, line 188
def min_wire_version
  @min_wire_version || 0
end
node_list() click to toggle source

Return a list of replica set nodes from the config. Note: this excludes arbiters.

# File lib/mongo/connection/node.rb, line 137
def node_list
  nodes = []
  nodes += config['hosts'] if config['hosts']
  nodes += config['passives'] if config['passives']
  nodes += ["#{@host}:#{@port}"] if @client.mongos?
  nodes
end
primary?() click to toggle source
# File lib/mongo/connection/node.rb, line 152
def primary?
  config['ismaster'] == true || config['ismaster'] == 1
end
secondary?() click to toggle source
# File lib/mongo/connection/node.rb, line 156
def secondary?
  config['secondary'] == true || config['secondary'] == 1
end
set_config() click to toggle source

Get the configuration for the provided node as returned by the ismaster command. Additionally, check that the replica set name matches with the name provided.

# File lib/mongo/connection/node.rb, line 101
def set_config
  @node_mutex.synchronize do
    begin
      if @config
        @last_state = @config['ismaster'] ? :primary : :other
      end

      if @client.connect_timeout
        Timeout::timeout(@client.connect_timeout, OperationTimeout) do
          @config = @client['admin'].command({:ismaster => 1}, :socket => usable_socket)
        end
      else
        @config = @client['admin'].command({:ismaster => 1}, :socket => usable_socket)
      end

      update_max_sizes

      if @config['msg']
        @client.log(:warn, "#{config['msg']}")
      end

      unless @client.mongos?
        check_set_membership(@config)
        check_set_name(@config)
      end
    rescue ConnectionFailure, OperationFailure, OperationTimeout, SocketError, SystemCallError, IOError => ex
      @client.log(:warn, "Attempted connection to node #{host_string} raised " +
                          "#{ex.class}: #{ex.message}")
      # Socket may already be nil from issuing command
      close
    end
  end
end
tags() click to toggle source
# File lib/mongo/connection/node.rb, line 160
def tags
  config['tags'] || {}
end
wire_version_feature?(feature) click to toggle source
# File lib/mongo/connection/node.rb, line 192
def wire_version_feature?(feature)
  min_wire_version <= feature && feature <= max_wire_version
end

Protected Instance Methods

check_set_membership(config) click to toggle source

Ensure that this node is a healthy member of a replica set.

# File lib/mongo/connection/node.rb, line 203
def check_set_membership(config)
  if !config.has_key?('hosts')
    message = "Will not connect to #{host_string} because it's not a member " +
      "of a replica set."
    raise ConnectionFailure, message
  elsif config['hosts'].length == 1 && !config['ismaster'] &&
    !config['secondary']
    message = "Attempting to connect to an unhealthy, single-node replica set."
    raise ConnectionFailure, message
  end
end
check_set_name(config) click to toggle source

Ensure that this node is part of a replica set of the expected name.

# File lib/mongo/connection/node.rb, line 216
def check_set_name(config)
  if @client.replica_set_name
    if !config['setName']
      @client.log(:warn, "Could not verify replica set name for member #{host_string} " +
        "because ismaster does not return name in this version of MongoDB")
    elsif @client.replica_set_name != config['setName']
      message = "Attempting to connect to replica set '#{config['setName']}' on member #{host_string} " +
        "but expected '#{@client.replica_set_name}'"
      raise ReplicaSetConnectionError, message
    end
  end
end

Private Instance Methods

update_max_sizes() click to toggle source
# File lib/mongo/connection/node.rb, line 241
def update_max_sizes
  @max_bson_size = config['maxBsonObjectSize'] || DEFAULT_MAX_BSON_SIZE
  @max_message_size = config['maxMessageSizeBytes'] || @max_bson_size * MESSAGE_SIZE_FACTOR
  @max_wire_version = config['maxWireVersion'] || 0
  @min_wire_version = config['minWireVersion'] || 0
  @max_write_batch_size = config['maxWriteBatchSize'] || Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE
end
usable_socket() click to toggle source
# File lib/mongo/connection/node.rb, line 231
def usable_socket
  if @socket && @socket.pid != Process.pid
    @socket.close
    @socket = nil
    connect
  else
    @socket
  end
end