@@ -40,6 +40,8 @@ public class TimeoutContext {
40
40
41
41
@ Nullable
42
42
private Timeout timeout ;
43
+ @ Nullable
44
+ private Timeout computedServerSelectionTimeout ;
43
45
private long minRoundTripTimeMS = 0 ;
44
46
45
47
public static MongoOperationTimeoutException createMongoTimeoutException () {
@@ -191,14 +193,17 @@ public long getWriteTimeoutMS() {
191
193
return timeoutOrAlternative (0 );
192
194
}
193
195
196
+ public int getConnectTimeoutMs () {
197
+ return (int ) calculateMin (getTimeoutSettings ().getConnectTimeoutMS ());
198
+ }
194
199
195
200
public void resetTimeout () {
196
201
assertNotNull (timeout );
197
202
timeout = calculateTimeout (timeoutSettings .getTimeoutMS ());
198
203
}
199
204
200
205
/**
201
- * Resest the timeout if this timeout context is being used by pool maintenance
206
+ * Resets the timeout if this timeout context is being used by pool maintenance
202
207
*/
203
208
public void resetMaintenanceTimeout () {
204
209
if (isMaintenanceContext && timeout != null && !timeout .isInfinite ()) {
@@ -265,23 +270,53 @@ public static Timeout calculateTimeout(@Nullable final Long timeoutMS) {
265
270
return null ;
266
271
}
267
272
273
+ /**
274
+ * Returns the computed server selection timeout
275
+ *
276
+ * <p>Caches the computed server selection timeout if:
277
+ * <ul>
278
+ * <li>not in a maintenance context</li>
279
+ * <li>there is a timeoutMS, so to keep the same legacy behavior.</li>
280
+ * <li>the server selection timeout is less than the remaining overall timeout.</li>
281
+ * </ul>
282
+ *
283
+ * @return the timeout context
284
+ */
268
285
public Timeout computedServerSelectionTimeout () {
269
- long ms = getTimeoutSettings ().getServerSelectionTimeoutMS ();
270
- Timeout serverSelectionTimeout = StartTime .now ().timeoutAfterOrInfiniteIfNegative (ms , MILLISECONDS );
271
- return serverSelectionTimeout .orEarlier (timeout );
286
+ Timeout serverSelectionTimeout = StartTime .now ()
287
+ .timeoutAfterOrInfiniteIfNegative (getTimeoutSettings ().getServerSelectionTimeoutMS (), MILLISECONDS );
288
+
289
+
290
+ if (isMaintenanceContext || !hasTimeoutMS ()) {
291
+ return serverSelectionTimeout ;
292
+ }
293
+
294
+ if (serverSelectionTimeout .orEarlier (timeout ) == timeout ) {
295
+ return timeout ;
296
+ }
297
+
298
+ computedServerSelectionTimeout = serverSelectionTimeout ;
299
+ return computedServerSelectionTimeout ;
300
+ }
301
+
302
+ /**
303
+ * Returns the timeout context to use for the handshake process
304
+ *
305
+ * @return a new timeout context with the cached computed server selection timeout if available or this
306
+ */
307
+ public TimeoutContext withComputedServerSelectionTimeoutContext () {
308
+ return computedServerSelectionTimeout == null
309
+ ? this : new TimeoutContext (false , timeoutSettings , computedServerSelectionTimeout );
272
310
}
273
311
274
312
public Timeout startWaitQueueTimeout (final StartTime checkoutStart ) {
275
313
final long ms = getTimeoutSettings ().getMaxWaitTimeMS ();
276
314
return checkoutStart .timeoutAfterOrInfiniteIfNegative (ms , MILLISECONDS );
277
315
}
278
316
279
- public int getConnectTimeoutMs () {
280
- return (int ) getTimeoutSettings ().getConnectTimeoutMS ();
281
- }
282
-
283
317
@ Nullable
284
318
public Timeout getTimeout () {
285
319
return timeout ;
286
320
}
321
+
287
322
}
0 commit comments