Skip to content

Commit

Permalink
RUBY-1874 Add "connectionError" as a valid "reason" for a ConnectionC…
Browse files Browse the repository at this point in the history
…heckOutFailedEvent when connection set up fails (#1453)

* Add connectionError as a valid reason for a ConnectionCheckOutFailedEvent when connection setup fails

* Start populator after pool created event is emitted to enforce cmap event order

* use authorized client instead of local
  • Loading branch information
HanaPearlman committed Jul 19, 2019
1 parent bb6d00f commit 5386e8a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 7 deletions.
17 changes: 13 additions & 4 deletions lib/mongo/server/connection_pool.rb
Expand Up @@ -127,11 +127,11 @@ def initialize(server, options = {})

ObjectSpace.define_finalizer(self, self.class.finalize(@available_connections, @pending_connections, @populator))

@populator.run! if min_size > 0

publish_cmap_event(
Monitoring::Event::Cmap::PoolCreated.new(@server.address, options)
)

@populator.run! if min_size > 0
end

# @return [ Hash ] options The pool options.
Expand Down Expand Up @@ -243,17 +243,26 @@ def closed?
# checked back in via the check_in method.
#
# @return [ Mongo::Server::Connection ] The checked out connection.
# @raise [ Error::PoolClosedError ] If the pool has been closed.
# @raise [ Timeout::Error ] If the connection pool is at maximum size
# and remains so for longer than the wait timeout.
#
# @since 2.9.0
def check_out
raise_if_closed!

publish_cmap_event(
Monitoring::Event::Cmap::ConnectionCheckOutStarted.new(@server.address)
)

if closed?
publish_cmap_event(
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
@server.address,
Monitoring::Event::Cmap::ConnectionCheckOutFailed::POOL_CLOSED
),
)
raise Error::PoolClosedError.new(@server.address)
end

deadline = Time.now + wait_timeout
connection = nil
# It seems that synchronize sets up its own loop, thus a simple break
Expand Down
4 changes: 2 additions & 2 deletions spec/mongo/server/connection_pool_populator_spec.rb
Expand Up @@ -246,15 +246,15 @@
context 'when populate encounters a network error twice' do
it 'retries once and does not stop the populator' do
expect(pool).to receive(:create_and_add_connection).twice.and_raise(Mongo::Error::SocketError)
sleep 0.5
sleep 2
expect(pool.instance_variable_get('@populator').running?).to be true
end
end

context 'when populate encounters a non-network error' do
it 'does not retry and does not stop the populator' do
expect(pool).to receive(:create_and_add_connection).and_raise(Mongo::Error)
sleep 0.5
sleep 2
expect(pool.instance_variable_get('@populator').running?).to be true
end
end
Expand Down
28 changes: 28 additions & 0 deletions spec/mongo/server/connection_pool_spec.rb
Expand Up @@ -497,6 +497,34 @@
end.to raise_error(Mongo::Error::PoolClosedError)
end
end

context 'when connection set up throws an error during check out' do
let(:client) do
authorized_client
end

let(:pool) do
client.cluster.next_primary.pool
end

it 'raises an error and emits ConnectionCheckOutFailedEvent' do
pool

subscriber = EventSubscriber.new
client.subscribe(Mongo::Monitoring::CONNECTION_POOL, subscriber)

subscriber.clear_events!
expect(Mongo::Auth).to receive(:get).at_least(:once).and_raise(Mongo::Error)
expect { pool.check_out }.to raise_error(Mongo::Error)
expect(pool.size).to eq(0)

checkout_failed_events = subscriber.published_events.select do |event|
event.is_a?(Mongo::Monitoring::Event::Cmap::ConnectionCheckOutFailed)
end
expect(checkout_failed_events.size).to eq(1)
expect(checkout_failed_events.first.reason).to be(:connection_error)
end
end
end

describe '#disconnect!' do
Expand Down
5 changes: 4 additions & 1 deletion spec/spec_tests/data/cmap/pool-checkout-error-closed.yml
Expand Up @@ -15,14 +15,17 @@ events:
- type: ConnectionPoolCreated
address: 42
options: 42
- type: ConnectionCheckOutStarted
- type: ConnectionCheckedOut
connectionId: 42
- type: ConnectionCheckedIn
connectionId: 42
- type: ConnectionPoolClosed
address: 42
- type: ConnectionCheckOutStarted
- type: ConnectionCheckOutFailed
reason: poolClosed
ignore:
- ConnectionCreated
- ConnectionReady
- ConnectionClosed
- ConnectionCheckOutStarted

0 comments on commit 5386e8a

Please sign in to comment.