Skip to content

Commit 0ecac8c

Browse files
authored
Accept long instead of int in SocketSettings.Builder.connectTimeout/readTimeout (#1279)
* Accept `long` instead of `int` in `SocketSettings.Builder.connectTimeout`/`readTimeout` JAVA-3897
1 parent 89512cd commit 0ecac8c

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

driver-core/src/main/com/mongodb/connection/SocketSettings.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import com.mongodb.ConnectionString;
2121
import com.mongodb.annotations.Immutable;
2222

23+
import java.util.Objects;
2324
import java.util.concurrent.TimeUnit;
2425

2526
import static com.mongodb.assertions.Assertions.notNull;
27+
import static java.lang.Math.toIntExact;
2628
import static java.util.concurrent.TimeUnit.MILLISECONDS;
2729

2830
/**
@@ -32,8 +34,8 @@
3234
*/
3335
@Immutable
3436
public final class SocketSettings {
35-
private final long connectTimeoutMS;
36-
private final long readTimeoutMS;
37+
private final int connectTimeoutMS;
38+
private final int readTimeoutMS;
3739
private final int receiveBufferSize;
3840
private final int sendBufferSize;
3941
private final ProxySettings proxySettings;
@@ -62,8 +64,8 @@ public static Builder builder(final SocketSettings socketSettings) {
6264
* A builder for an instance of {@code SocketSettings}.
6365
*/
6466
public static final class Builder {
65-
private long connectTimeoutMS = 10000;
66-
private long readTimeoutMS;
67+
private int connectTimeoutMS = 10000;
68+
private int readTimeoutMS;
6769
private int receiveBufferSize;
6870
private int sendBufferSize;
6971
private ProxySettings.Builder proxySettingsBuilder = ProxySettings.builder();
@@ -93,25 +95,27 @@ public Builder applySettings(final SocketSettings socketSettings) {
9395
/**
9496
* Sets the socket connect timeout.
9597
*
96-
* @param connectTimeout the connect timeout
98+
* @param connectTimeout the connect timeout.
99+
* The timeout converted to milliseconds must not be greater than {@link Integer#MAX_VALUE}.
97100
* @param timeUnit the time unit
98101
* @return this
99102
*/
100-
public Builder connectTimeout(final int connectTimeout, final TimeUnit timeUnit) {
101-
this.connectTimeoutMS = MILLISECONDS.convert(connectTimeout, timeUnit);
103+
public Builder connectTimeout(final long connectTimeout, final TimeUnit timeUnit) {
104+
this.connectTimeoutMS = timeoutArgumentToMillis(connectTimeout, timeUnit);
102105
return this;
103106
}
104107

105108
/**
106109
* Sets the socket read timeout.
107110
*
108-
* @param readTimeout the read timeout
111+
* @param readTimeout the read timeout.
112+
* The timeout converted to milliseconds must not be greater than {@link Integer#MAX_VALUE}.
109113
* @param timeUnit the time unit
110114
* @return this
111115
* @see #getReadTimeout(TimeUnit)
112116
*/
113-
public Builder readTimeout(final int readTimeout, final TimeUnit timeUnit) {
114-
this.readTimeoutMS = MILLISECONDS.convert(readTimeout, timeUnit);
117+
public Builder readTimeout(final long readTimeout, final TimeUnit timeUnit) {
118+
this.readTimeoutMS = timeoutArgumentToMillis(readTimeout, timeUnit);
115119
return this;
116120
}
117121

@@ -197,7 +201,7 @@ public int getConnectTimeout(final TimeUnit timeUnit) {
197201
*
198202
* @param timeUnit the time unit to get the timeout in
199203
* @return the read timeout in the requested time unit, or 0 if there is no timeout
200-
* @see Builder#readTimeout(int, TimeUnit)
204+
* @see Builder#readTimeout(long, TimeUnit)
201205
*/
202206
public int getReadTimeout(final TimeUnit timeUnit) {
203207
return (int) timeUnit.convert(readTimeoutMS, MILLISECONDS);
@@ -260,12 +264,7 @@ public boolean equals(final Object o) {
260264

261265
@Override
262266
public int hashCode() {
263-
int result = (int) (connectTimeoutMS ^ (connectTimeoutMS >>> 32));
264-
result = 31 * result + (int) (readTimeoutMS ^ (readTimeoutMS >>> 32));
265-
result = 31 * result + receiveBufferSize;
266-
result = 31 * result + sendBufferSize;
267-
result = 31 * result + proxySettings.hashCode();
268-
return result;
267+
return Objects.hash(connectTimeoutMS, readTimeoutMS, receiveBufferSize, sendBufferSize, proxySettings);
269268
}
270269

271270
@Override
@@ -285,4 +284,13 @@ private SocketSettings(final Builder builder) {
285284
sendBufferSize = builder.sendBufferSize;
286285
proxySettings = builder.proxySettingsBuilder.build();
287286
}
287+
288+
private static int timeoutArgumentToMillis(final long timeout, final TimeUnit timeUnit) throws IllegalArgumentException {
289+
try {
290+
return toIntExact(MILLISECONDS.convert(timeout, timeUnit));
291+
} catch (ArithmeticException e) {
292+
throw new IllegalArgumentException(
293+
"The timeout converted to milliseconds must not be greater than `Integer.MAX_VALUE`", e);
294+
}
295+
}
288296
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import spock.lang.Specification
2121

2222
import static java.util.concurrent.TimeUnit.MILLISECONDS
2323

24-
24+
/**
25+
* New unit tests for {@link SocketSettings} are to be added to {@link SocketSettingsTest}.
26+
*/
2527
class SocketSettingsSpecification extends Specification {
2628

2729
def 'should have correct defaults'() {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.mongodb.connection;
17+
18+
import org.junit.jupiter.api.Test;
19+
20+
import java.util.concurrent.TimeUnit;
21+
22+
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
24+
/**
25+
* {@link SocketSettingsSpecification} contains older unit tests for {@link SocketSettings}.
26+
*/
27+
final class SocketSettingsTest {
28+
@Test
29+
void connectTimeoutThrowsIfArgumentIsTooLarge() {
30+
assertThrows(IllegalArgumentException.class, () -> SocketSettings.builder().connectTimeout(Integer.MAX_VALUE / 2, TimeUnit.SECONDS));
31+
}
32+
33+
@Test
34+
void readTimeoutThrowsIfArgumentIsTooLarge() {
35+
assertThrows(IllegalArgumentException.class, () -> SocketSettings.builder().readTimeout(Integer.MAX_VALUE / 2, TimeUnit.SECONDS));
36+
}
37+
}

0 commit comments

Comments
 (0)