Raise exception if connecting to single slave with slave_ok set to false; pass slave_ok on to queries when set to true.
This commit is contained in:
parent
c6d4150a51
commit
4e2781faf1
@ -130,7 +130,7 @@ module Mongo
|
||||
end
|
||||
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
|
||||
|
||||
cursor = @db.query(self, Query.new(selector, fields, skip, limit, sort, hint, snapshot, timeout))
|
||||
cursor = @db.query(self, Query.new(selector, fields, skip, limit, sort, hint, snapshot, timeout, @db.slave_ok?))
|
||||
if block_given?
|
||||
yield cursor
|
||||
cursor.close()
|
||||
|
@ -160,6 +160,9 @@ module Mongo
|
||||
is_master = master?
|
||||
@semaphore.lock if semaphore_is_locked
|
||||
|
||||
if !@slave_ok && !is_master
|
||||
raise ConfigurationError, "Trying to connect directly to slave; if this is what you want, specify :slave_ok => true."
|
||||
end
|
||||
@slave_ok || is_master
|
||||
rescue SocketError, SystemCallError, IOError => ex
|
||||
close if @socket
|
||||
|
@ -15,6 +15,12 @@
|
||||
# Exceptions raised by the MongoDB driver.
|
||||
|
||||
module Mongo
|
||||
# Generic Mongo Ruby Driver exception class.
|
||||
class MongoRubyError < StandardError; end
|
||||
|
||||
# Raised when configuration options cause connections, queries, etc., to fail.
|
||||
class ConfigurationError < MongoRubyError; end
|
||||
|
||||
# Raised when a database operation fails.
|
||||
class OperationFailure < RuntimeError; end
|
||||
|
||||
|
@ -25,5 +25,6 @@ module Mongo
|
||||
OP_DELETE = 2006
|
||||
OP_KILL_CURSORS = 2007
|
||||
|
||||
OP_QUERY_SLAVE_OK = 4
|
||||
OP_QUERY_NO_CURSOR_TIMEOUT = 16
|
||||
end
|
||||
|
@ -67,9 +67,9 @@ module Mongo
|
||||
# the normal cursor timeout behavior of the mongod process.
|
||||
# When +false+, the returned cursor will never timeout. Care should
|
||||
# be taken to ensure that cursors with timeout disabled are properly closed.
|
||||
def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil, timeout=true)
|
||||
@number_to_skip, @number_to_return, @order_by, @hint, @snapshot, @timeout =
|
||||
number_to_skip, number_to_return, order_by, hint, snapshot, timeout
|
||||
def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil, timeout=true, slave_ok=false)
|
||||
@number_to_skip, @number_to_return, @order_by, @hint, @snapshot, @timeout, @slave_ok =
|
||||
number_to_skip, number_to_return, order_by, hint, snapshot, timeout, slave_ok
|
||||
@explain = nil
|
||||
self.selector = sel
|
||||
self.fields = return_fields
|
||||
@ -121,7 +121,9 @@ module Mongo
|
||||
# Returns an integer indicating which query options have been selected.
|
||||
# See http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol#MongoWireProtocol-OPQUERY
|
||||
def query_opts
|
||||
@timeout ? 0 : OP_QUERY_NO_CURSOR_TIMEOUT
|
||||
timeout = @timeout ? 0 : OP_QUERY_NO_CURSOR_TIMEOUT
|
||||
slave_ok = @slave_ok ? OP_QUERY_SLAVE_OK : 0
|
||||
slave_ok + timeout
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -37,4 +37,22 @@ class TestQueryMessage < Test::Unit::TestCase
|
||||
assert_equal 16, buf[16]
|
||||
end
|
||||
|
||||
def test_timeout_opcodes
|
||||
@timeout = true
|
||||
@slave_ok = true
|
||||
@query = Query.new({}, nil, 0, 0, nil, nil, nil, @timeout, @slave_ok)
|
||||
@query_message = QueryMessage.new('db', 'collection', @query)
|
||||
buf = @query_message.buf.instance_variable_get(:@buf)
|
||||
assert_equal 4, buf[16]
|
||||
|
||||
|
||||
@timeout = false
|
||||
@slave_ok = true
|
||||
@query = Query.new({}, nil, 0, 0, nil, nil, nil, @timeout, @slave_ok)
|
||||
@query_message = QueryMessage.new('db', 'collection', @query)
|
||||
buf = @query_message.buf.instance_variable_get(:@buf)
|
||||
assert_equal 20, buf[16]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
@ -33,4 +33,22 @@ class TestQuery < Test::Unit::TestCase
|
||||
assert_equal 16, @query.query_opts
|
||||
end
|
||||
|
||||
def test_slave_ok_opcodes
|
||||
@slave_ok = true
|
||||
@query = Query.new({}, nil, 0, 0, nil, nil, nil, true, @slave_ok)
|
||||
assert_equal 4, @query.query_opts
|
||||
|
||||
|
||||
@slave_ok = false
|
||||
@query = Query.new({}, nil, 0, 0, nil, nil, nil, true, @slave_ok)
|
||||
assert_equal 0, @query.query_opts
|
||||
end
|
||||
|
||||
def test_combined_opcodes
|
||||
@timeout = false
|
||||
@slave_ok = true
|
||||
@query = Query.new({}, nil, 0, 0, nil, nil, nil, @timeout, @slave_ok)
|
||||
assert_equal 20, @query.query_opts
|
||||
end
|
||||
|
||||
end
|
||||
|
42
test/test_slave_connection.rb
Normal file
42
test/test_slave_connection.rb
Normal file
@ -0,0 +1,42 @@
|
||||
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
||||
require 'mongo'
|
||||
require 'test/unit'
|
||||
|
||||
# NOTE: these tests are run only if we can connect to a single MongoDB in slave mode.
|
||||
class SlaveConnectionTest < Test::Unit::TestCase
|
||||
include Mongo
|
||||
|
||||
def self.connect_to_slave
|
||||
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
||||
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
||||
db = Connection.new(@@host, @@port, :slave_ok => true).db('ruby-mongo-demo')
|
||||
!db.master?
|
||||
end
|
||||
|
||||
if self.connect_to_slave
|
||||
puts "Connected to slave; running slave tests."
|
||||
|
||||
def test_connect_to_slave
|
||||
assert_raise Mongo::ConfigurationError do
|
||||
@db = Connection.new(@@host, @@port, :slave_ok => false).db('ruby-mongo-demo')
|
||||
end
|
||||
end
|
||||
|
||||
def test_slave_ok_sent_to_queries
|
||||
@db = Connection.new(@@host, @@port, :slave_ok => true).db('ruby-mongo-demo')
|
||||
@coll = @db['test-collection']
|
||||
@cursor = @coll.find({})
|
||||
assert_equal true, @cursor.query.instance_variable_get(:@slave_ok)
|
||||
end
|
||||
else
|
||||
puts "Not connected to slave; skipping slave connection tests."
|
||||
|
||||
def test_slave_ok_false_on_queries
|
||||
@db = Connection.new(@@host, @@port).db('ruby-mongo-demo')
|
||||
@coll = @db['test-collection']
|
||||
@cursor = @coll.find({})
|
||||
assert_nil @cursor.query.instance_variable_get(:@slave_ok)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user