Skip to content

Commit 012e79f

Browse files
p-mongop
andcommitted
Fix RUBY-2805 Push monitor thread can exit when address resolution fails (#2356)
Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent 33ece34 commit 012e79f

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

lib/mongo/server/push_monitor.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def do_work
110110
if new_description.topology_version
111111
@topology_version = new_description.topology_version
112112
end
113-
rescue Mongo::Error => exc
113+
rescue IOError, SocketError, SystemCallError, Mongo::Error => exc
114114
stop_requested = @lock.synchronize { @stop_requested }
115115
if stop_requested
116116
# Ignore the exception, see RUBY-2771.

spec/mongo/server/monitor/connection_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,28 @@
136136
end
137137
end
138138

139+
describe '#connect!' do
140+
141+
let(:options) do
142+
SpecConfig.instance.test_options.merge(
143+
app_metadata: monitor_app_metadata,
144+
)
145+
end
146+
147+
context 'when address resolution fails' do
148+
let(:connection) { described_class.new(server.address, options) }
149+
150+
it 'propagates the exception' do
151+
connection
152+
153+
expect(Socket).to receive(:getaddrinfo).and_raise(SocketError.new('Test exception'))
154+
lambda do
155+
connection.connect!
156+
end.should raise_error(SocketError, 'Test exception')
157+
end
158+
end
159+
end
160+
139161
describe '#check_document' do
140162
context 'with API version' do
141163
let(:meta) do
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# frozen_string_literal: true
2+
# encoding: utf-8
3+
4+
require 'spec_helper'
5+
6+
describe Mongo::Server::PushMonitor do
7+
before(:all) do
8+
ClientRegistry.instance.close_all_clients
9+
end
10+
11+
let(:address) do
12+
default_address
13+
end
14+
15+
let(:listeners) do
16+
Mongo::Event::Listeners.new
17+
end
18+
19+
let(:monitor_options) do
20+
{}
21+
end
22+
23+
let(:monitor_app_metadata) do
24+
Mongo::Server::Monitor::AppMetadata.new(
25+
server_api: SpecConfig.instance.ruby_options[:server_api],
26+
)
27+
end
28+
29+
let(:cluster) do
30+
double('cluster').tap do |cluster|
31+
allow(cluster).to receive(:run_sdam_flow)
32+
allow(cluster).to receive(:heartbeat_interval).and_return(1000)
33+
end
34+
end
35+
36+
let(:server) do
37+
Mongo::Server.new(address, cluster, Mongo::Monitoring.new, listeners,
38+
monitoring_io: false)
39+
end
40+
41+
let(:monitor) do
42+
register_background_thread_object(
43+
Mongo::Server::Monitor.new(server, listeners, Mongo::Monitoring.new,
44+
SpecConfig.instance.test_options.merge(cluster: cluster).merge(monitor_options).update(
45+
app_metadata: monitor_app_metadata,
46+
push_monitor_app_metadata: monitor_app_metadata))
47+
)
48+
end
49+
50+
let(:topology_version) do
51+
Mongo::TopologyVersion.new('processId' => BSON::ObjectId.new, 'counter' => 1)
52+
end
53+
54+
let(:check_document) do
55+
{hello: 1}
56+
end
57+
58+
let(:push_monitor) do
59+
described_class.new(monitor, topology_version, monitor.monitoring,
60+
**monitor.options.merge(check_document: check_document))
61+
end
62+
63+
describe '#do_work' do
64+
it 'works' do
65+
lambda do
66+
push_monitor.do_work
67+
end.should_not raise_error
68+
end
69+
70+
context 'network error during check' do
71+
it 'does not propagate the exception' do
72+
push_monitor
73+
74+
expect(Socket).to receive(:getaddrinfo).and_raise(SocketError.new('Test exception'))
75+
lambda do
76+
push_monitor.do_work
77+
end.should_not raise_error
78+
end
79+
end
80+
end
81+
82+
end

0 commit comments

Comments
 (0)