diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java index 48ee8b287..62391eb10 100644 --- a/core/src/main/java/com/arangodb/ArangoDB.java +++ b/core/src/main/java/com/arangodb/ArangoDB.java @@ -513,9 +513,10 @@ public Builder maxConnections(final Integer maxConnections) { } /** - * Set the maximum time to life of a connection. After this time the connection will be closed automatically. + * Set the time to live of an inactive connection. After this time of inactivity the connection will be + * closed automatically. * - * @param connectionTtl the maximum time to life of a connection in milliseconds + * @param connectionTtl the time to live of a connection in milliseconds * @return {@link ArangoDB.Builder} */ public Builder connectionTtl(final Long connectionTtl) { diff --git a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java index aab635dd3..4e182970d 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java +++ b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java @@ -45,6 +45,7 @@ public final class ArangoDefaults { public static final Protocol DEFAULT_PROTOCOL = Protocol.HTTP2_JSON; public static final String DEFAULT_USER = "root"; public static final Integer DEFAULT_TIMEOUT = 0; + public static final Long DEFAULT_CONNECTION_TTL_HTTP = 30_000L; public static final Boolean DEFAULT_USE_SSL = false; public static final Boolean DEFAULT_VERIFY_HOST = true; public static final Integer DEFAULT_CHUNK_SIZE = 30_000; diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index 0aa67812f..e01a40c9a 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java @@ -219,6 +219,9 @@ public void setMaxConnections(Integer maxConnections) { } public Long getConnectionTtl() { + if (connectionTtl == null && getProtocol() != Protocol.VST) { + connectionTtl = ArangoDefaults.DEFAULT_CONNECTION_TTL_HTTP; + } return connectionTtl; } diff --git a/resilience-tests/src/test/java/resilience/ClusterTest.java b/resilience-tests/src/test/java/resilience/ClusterTest.java index d16f4cbfa..7068927e1 100644 --- a/resilience-tests/src/test/java/resilience/ClusterTest.java +++ b/resilience-tests/src/test/java/resilience/ClusterTest.java @@ -52,6 +52,7 @@ static void afterAll() throws IOException { @BeforeEach void beforeEach() { enableAllEndpoints(); + logs.reset(); } protected static List getEndpoints() { diff --git a/resilience-tests/src/test/java/resilience/SingleServerTest.java b/resilience-tests/src/test/java/resilience/SingleServerTest.java index 3aa587d93..89d028469 100644 --- a/resilience-tests/src/test/java/resilience/SingleServerTest.java +++ b/resilience-tests/src/test/java/resilience/SingleServerTest.java @@ -37,6 +37,7 @@ static void afterAll() throws IOException { @BeforeEach void beforeEach() { getEndpoint().enable(); + logs.reset(); } protected static Endpoint getEndpoint() { diff --git a/resilience-tests/src/test/java/resilience/ttl/TtlTest.java b/resilience-tests/src/test/java/resilience/ttl/TtlTest.java new file mode 100644 index 000000000..66aa37033 --- /dev/null +++ b/resilience-tests/src/test/java/resilience/ttl/TtlTest.java @@ -0,0 +1,68 @@ +package resilience.ttl; + +import com.arangodb.ArangoDB; +import com.arangodb.ArangoDBAsync; +import com.arangodb.Protocol; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import resilience.SingleServerTest; + +import java.time.Duration; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import static org.awaitility.Awaitility.await; + +/** + * @author Michele Rastelli + */ +class TtlTest extends SingleServerTest { + + static Stream args() { + return Stream.of( + Arguments.of(Protocol.HTTP_JSON, "UNREGISTERED"), + Arguments.of(Protocol.HTTP2_JSON, "OUTBOUND GO_AWAY") + ); + } + + @ParameterizedTest + @MethodSource("args") + void connectionTtl(Protocol p, String expectedLog) { + ArangoDB arangoDB = dbBuilder() + .connectionTtl(1_000L) + .maxConnections(1) + .protocol(p) + .build(); + + arangoDB.getVersion(); + + await() + .timeout(Duration.ofSeconds(3)) + .until(() -> logs.getLogs().anyMatch(it -> it.getFormattedMessage().contains(expectedLog))); + + arangoDB.getVersion(); + arangoDB.shutdown(); + } + + @ParameterizedTest + @MethodSource("args") + void connectionTtlAsync(Protocol p, String expectedLog) throws ExecutionException, InterruptedException { + ArangoDBAsync arangoDB = dbBuilder() + .connectionTtl(1_000L) + .maxConnections(1) + .protocol(p) + .build() + .async(); + + arangoDB.getVersion().get(); + + await() + .timeout(Duration.ofSeconds(3)) + .until(() -> logs.getLogs().anyMatch(it -> it.getFormattedMessage().contains(expectedLog))); + + arangoDB.getVersion().get(); + arangoDB.shutdown(); + } + +} diff --git a/vst/src/main/java/com/arangodb/vst/internal/VstConnection.java b/vst/src/main/java/com/arangodb/vst/internal/VstConnection.java index 8d9339463..ddd886d10 100644 --- a/vst/src/main/java/com/arangodb/vst/internal/VstConnection.java +++ b/vst/src/main/java/com/arangodb/vst/internal/VstConnection.java @@ -183,7 +183,7 @@ public synchronized void open() throws IOException { LOGGER.debug("[" + connectionName + "]: Start Callable"); final long openTime = new Date().getTime(); - final Long ttlTime = ttl != null ? openTime + ttl : null; + final Long ttlTime = ttl != null && ttl > 0 ? openTime + ttl : null; final ChunkStore chunkStore = new ChunkStore(messageStore); while (true) { if (ttlTime != null && new Date().getTime() > ttlTime && messageStore.isEmpty()) {