Skip to content

Commit

Permalink
Allow specification of replica set name on connect.
Browse files Browse the repository at this point in the history
Raise ReplicaSetConnectionError if expected name doesn't match set.
  • Loading branch information
banker committed Nov 3, 2010
1 parent 6e00094 commit d6f8f9d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
24 changes: 24 additions & 0 deletions lib/mongo/connection.rb
Expand Up @@ -64,6 +64,8 @@ class Connection
# @option options [Boolean] :slave_ok (false) Must be set to +true+ when connecting
# to a single, slave node.
# @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
# @option options [String] :name (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.
# @option options [Integer] :pool_size (1) The maximum number of socket connections that can be
# opened to the database.
# @option options [Float] :timeout (5.0) When all of the connections to the pool are checked out,
Expand All @@ -83,6 +85,9 @@ class Connection
#
# @see http://www.mongodb.org/display/DOCS/Replica+Pairs+in+Ruby Replica pairs 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.
#
# @core connections
def initialize(host=nil, port=nil, options={})
@auths = []
Expand All @@ -96,6 +101,9 @@ def initialize(host=nil, port=nil, options={})
# Host and port of current master.
@host = @port = nil

# Replica set name
@replica_set_name = options[:name]

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

Expand Down Expand Up @@ -600,6 +608,7 @@ def check_is_master(node)

config = self['admin'].command({:ismaster => 1}, :sock => socket)

check_set_name(config, socket)
rescue OperationFailure, SocketError, SystemCallError, IOError => ex
close unless connected?
ensure
Expand All @@ -617,6 +626,21 @@ def check_is_master(node)
config
end

# Make sure that we're connected to the expected replica set.
def check_set_name(config, socket)
if @replica_set_name
config = self['admin'].command({:replSetGetStatus => 1},
:sock => socket, :check_response => false)

if !Mongo::Support.ok?(config)
raise ReplicaSetConnectionError, config['errmsg']
elsif config['set'] != @replica_set_name
raise ReplicaSetConnectionError,
"Attempting to connect to replica set '#{config['set']}' but expected '#{@replica_set_name}'"
end
end
end

# Set the specified node as primary, and
# apply any saved authentication credentials.
def set_primary(node)
Expand Down
3 changes: 3 additions & 0 deletions lib/mongo/exceptions.rb
Expand Up @@ -42,6 +42,9 @@ class MongoArgumentError < MongoRubyError; end
# Raised on failures in connection to the database server.
class ConnectionError < MongoRubyError; end

# Raised on failures in connection to the database server.
class ReplicaSetConnectionError < ConnectionError; end

# Raised on failures in connection to the database server.
class ConnectionTimeoutError < MongoRubyError; end

Expand Down
6 changes: 6 additions & 0 deletions test/connection_test.rb
Expand Up @@ -43,6 +43,12 @@ def test_invalid_database_names
assert_raise Mongo::InvalidNSName do @conn.db('te st') end
end

def test_replica_set_connection_name
assert_raise_error(Mongo::ReplicaSetConnectionError, "replSet") do
standard_connection(:name => "replica-set-foo")
end
end

def test_options_passed_to_db
@pk_mock = Object.new
db = @conn.db('test', :pk => @pk_mock, :strict => true)
Expand Down
10 changes: 9 additions & 1 deletion test/replica_sets/connect_test.rb
Expand Up @@ -7,8 +7,16 @@
class ConnectTest < Test::Unit::TestCase
include Mongo

def test_connect_bad_name
assert_raise_error(ReplicaSetConnectionError, "expected 'wrong-repl-set-name'") do
Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]],
:name => "wrong-repl-set-name")
end
end

def test_connect
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]])
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]],
:name => "foo")
assert @conn.connected?
end

Expand Down

0 comments on commit d6f8f9d

Please sign in to comment.