diff --git a/lib/mongo/connection.rb b/lib/mongo/connection.rb index c43bc56..11aee30 100644 --- a/lib/mongo/connection.rb +++ b/lib/mongo/connection.rb @@ -482,6 +482,22 @@ module Mongo @primary_pool && @primary_pool.host && @primary_pool.port end + # Determine if the connection is active. In a normal case the *server_info* operation + # will be performed without issues, but if the connection was dropped by the server or + # for some reason the sockets are unsynchronized, a ConnectionFailure will be raised and + # the return will be false. + # + # @return [Boolean] + def active? + return false unless connected? + + server_info + true + + rescue ConnectionFailure + false + end + # Determine whether we're reading from a primary node. If false, # this connection connects to a secondary node and @slave_ok is true. # diff --git a/test/connection_test.rb b/test/connection_test.rb index 9aefbb9..9b6dc0f 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -200,6 +200,26 @@ class TestConnection < Test::Unit::TestCase assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, BSON::BSON_CODER.max_bson_size end + def test_connection_activity + conn = standard_connection + assert conn.active? + + conn.primary_pool.close + assert !conn.active? + + # Simulate a dropped connection. + dropped_socket = Mocha::Mock.new + dropped_socket.stubs(:read).raises(Errno::ECONNRESET) + dropped_socket.stubs(:send).raises(Errno::ECONNRESET) + dropped_socket.stub_everything + + conn.primary_pool.host = 'localhost' + conn.primary_pool.port = Mongo::Connection::DEFAULT_PORT + conn.primary_pool.instance_variable_set("@sockets", [dropped_socket]) + + assert !conn.active? + end + context "Saved authentications" do setup do @conn = standard_connection