Skip to content

Commit b7e461f

Browse files
committed
Start roundTripTimeMonitor only if the streaming protocol is used
This change is in accordance with source/server-discovery-and-monitoring/server-monitoring.rst. JAVA-4936
1 parent 640fd79 commit b7e461f

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

driver-core/src/main/com/mongodb/internal/connection/DefaultServerMonitor.java

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ class DefaultServerMonitor implements ServerMonitor {
7979
private final ServerApi serverApi;
8080
private final boolean faas;
8181
private final ServerSettings serverSettings;
82-
private final ServerMonitorRunnable monitor;
83-
private final Thread monitorThread;
84-
private final RoundTripTimeRunnable roundTripTimeMonitor;
82+
private final ServerMonitor monitor;
83+
/**
84+
* Must be guarded by {@link #lock}.
85+
*/
86+
@Nullable
87+
private RoundTripTimeMonitor roundTripTimeMonitor;
8588
private final ExponentiallyWeightedMovingAverage averageRoundTripTime = new ExponentiallyWeightedMovingAverage(0.2);
86-
private final Thread roundTripTimeMonitorThread;
8789
private final Lock lock = new ReentrantLock();
8890
private final Condition condition = lock.newCondition();
8991
private volatile boolean isClosed;
@@ -102,20 +104,26 @@ class DefaultServerMonitor implements ServerMonitor {
102104
this.serverApi = serverApi;
103105
this.faas = faas;
104106
this.sdamProvider = sdamProvider;
105-
monitor = new ServerMonitorRunnable();
106-
monitorThread = new Thread(monitor, "cluster-" + this.serverId.getClusterId() + "-" + this.serverId.getAddress());
107-
monitorThread.setDaemon(true);
108-
roundTripTimeMonitor = new RoundTripTimeRunnable();
109-
roundTripTimeMonitorThread = new Thread(roundTripTimeMonitor,
110-
"cluster-rtt-" + this.serverId.getClusterId() + "-" + this.serverId.getAddress());
111-
roundTripTimeMonitorThread.setDaemon(true);
107+
monitor = new ServerMonitor();
108+
roundTripTimeMonitor = null;
112109
isClosed = false;
113110
}
114111

115112
@Override
116113
public void start() {
117-
monitorThread.start();
118-
roundTripTimeMonitorThread.start();
114+
monitor.start();
115+
}
116+
117+
private void ensureRoundTripTimeMonitorStarted() {
118+
lock.lock();
119+
try {
120+
if (roundTripTimeMonitor == null) {
121+
roundTripTimeMonitor = new RoundTripTimeMonitor();
122+
roundTripTimeMonitor.start();
123+
}
124+
} finally {
125+
lock.unlock();
126+
}
119127
}
120128

121129
@Override
@@ -124,24 +132,35 @@ public void connect() {
124132
}
125133

126134
@Override
135+
@SuppressWarnings("try")
127136
public void close() {
128137
isClosed = true;
129-
monitor.close();
130-
monitorThread.interrupt();
131-
roundTripTimeMonitor.close();
132-
roundTripTimeMonitorThread.interrupt();
138+
withLock(lock, () -> {
139+
//noinspection EmptyTryBlock
140+
try (ServerMonitor ignoredAutoClosed = monitor;
141+
RoundTripTimeMonitor ignoredAutoClose2 = roundTripTimeMonitor) {
142+
// we are automatically closing resources here
143+
}
144+
});
133145
}
134146

135147
@Override
136148
public void cancelCurrentCheck() {
137149
monitor.cancelCurrentCheck();
138150
}
139151

140-
class ServerMonitorRunnable implements Runnable {
152+
class ServerMonitor extends Thread implements AutoCloseable {
141153
private volatile InternalConnection connection = null;
142154
private volatile boolean currentCheckCancelled;
143155

144-
void close() {
156+
ServerMonitor() {
157+
super("cluster-" + serverId.getClusterId() + "-" + serverId.getAddress());
158+
setDaemon(true);
159+
}
160+
161+
@Override
162+
public void close() {
163+
interrupt();
145164
InternalConnection connection = this.connection;
146165
if (connection != null) {
147166
connection.close();
@@ -155,6 +174,10 @@ public void run() {
155174
while (!isClosed) {
156175
ServerDescription previousServerDescription = currentServerDescription;
157176
currentServerDescription = lookupServerDescription(currentServerDescription);
177+
boolean shouldStreamResponses = shouldStreamResponses(currentServerDescription);
178+
if (shouldStreamResponses) {
179+
ensureRoundTripTimeMonitorStarted();
180+
}
158181

159182
if (isClosed) {
160183
continue;
@@ -169,7 +192,7 @@ public void run() {
169192
logStateChange(previousServerDescription, currentServerDescription);
170193
sdamProvider.get().update(currentServerDescription);
171194

172-
if ((shouldStreamResponses(currentServerDescription) && currentServerDescription.getType() != UNKNOWN)
195+
if ((shouldStreamResponses && currentServerDescription.getType() != UNKNOWN)
173196
|| (connection != null && connection.hasMoreToCome())
174197
|| (currentServerDescription.getException() instanceof MongoSocketException
175198
&& previousServerDescription.getType() != UNKNOWN)) {
@@ -202,16 +225,17 @@ private ServerDescription lookupServerDescription(final ServerDescription curren
202225
if (LOGGER.isDebugEnabled()) {
203226
LOGGER.debug(format("Checking status of %s", serverId.getAddress()));
204227
}
228+
boolean shouldStreamResponses = shouldStreamResponses(currentServerDescription);
205229
serverMonitorListener.serverHearbeatStarted(new ServerHeartbeatStartedEvent(
206-
connection.getDescription().getConnectionId(), shouldStreamResponses(currentServerDescription)));
230+
connection.getDescription().getConnectionId(), shouldStreamResponses));
207231

208232
long start = System.nanoTime();
209233
try {
210234
SessionContext sessionContext = NoOpSessionContext.INSTANCE;
211235
if (!connection.hasMoreToCome()) {
212236
BsonDocument helloDocument = new BsonDocument(getHandshakeCommandName(currentServerDescription), new BsonInt32(1))
213237
.append("helloOk", BsonBoolean.TRUE);
214-
if (shouldStreamResponses(currentServerDescription)) {
238+
if (shouldStreamResponses) {
215239
helloDocument.append("topologyVersion", assertNotNull(currentServerDescription.getTopologyVersion()).asDocument());
216240
helloDocument.append("maxAwaitTimeMS", new BsonInt64(serverSettings.getHeartbeatFrequency(MILLISECONDS)));
217241
}
@@ -221,23 +245,26 @@ private ServerDescription lookupServerDescription(final ServerDescription curren
221245
}
222246

223247
BsonDocument helloResult;
224-
if (shouldStreamResponses(currentServerDescription)) {
248+
if (shouldStreamResponses) {
225249
helloResult = connection.receive(new BsonDocumentCodec(), sessionContext,
226250
Math.toIntExact(serverSettings.getHeartbeatFrequency(MILLISECONDS)));
227251
} else {
228252
helloResult = connection.receive(new BsonDocumentCodec(), sessionContext);
229253
}
230254

231255
long elapsedTimeNanos = System.nanoTime() - start;
256+
if (!shouldStreamResponses) {
257+
averageRoundTripTime.addSample(elapsedTimeNanos);
258+
}
232259
serverMonitorListener.serverHeartbeatSucceeded(
233260
new ServerHeartbeatSucceededEvent(connection.getDescription().getConnectionId(), helloResult,
234-
elapsedTimeNanos, shouldStreamResponses(currentServerDescription)));
261+
elapsedTimeNanos, shouldStreamResponses));
235262

236263
return createServerDescription(serverId.getAddress(), helloResult, averageRoundTripTime.getAverage());
237264
} catch (Exception e) {
238265
serverMonitorListener.serverHeartbeatFailed(
239266
new ServerHeartbeatFailedEvent(connection.getDescription().getConnectionId(), System.nanoTime() - start,
240-
shouldStreamResponses(currentServerDescription), e));
267+
shouldStreamResponses, e));
241268
throw e;
242269
}
243270
} catch (Throwable t) {
@@ -399,10 +426,17 @@ static boolean shouldLogStageChange(final ServerDescription previous, final Serv
399426
}
400427

401428

402-
private class RoundTripTimeRunnable implements Runnable {
429+
private class RoundTripTimeMonitor extends Thread implements AutoCloseable {
403430
private volatile InternalConnection connection = null;
404431

405-
void close() {
432+
RoundTripTimeMonitor() {
433+
super("cluster-rtt-" + serverId.getClusterId() + "-" + serverId.getAddress());
434+
setDaemon(true);
435+
}
436+
437+
@Override
438+
public void close() {
439+
interrupt();
406440
InternalConnection connection = this.connection;
407441
if (connection != null) {
408442
connection.close();

driver-core/src/test/unit/com/mongodb/internal/connection/DefaultServerMonitorSpecification.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class DefaultServerMonitorSpecification extends Specification {
8989

9090
when:
9191
monitor.close()
92-
monitor.monitorThread.join()
92+
monitor.monitor.join()
9393

9494
then:
9595
!stateChanged

0 commit comments

Comments
 (0)