diff --git a/core/pom.xml b/core/pom.xml
index df4126689..7e7c87a39 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
core
diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java
index a865e0306..7ebdb2e7e 100644
--- a/core/src/main/java/com/arangodb/ArangoDB.java
+++ b/core/src/main/java/com/arangodb/ArangoDB.java
@@ -517,6 +517,17 @@ public Builder chunkSize(final Integer chunkSize) {
return this;
}
+ /**
+ * Set whether to use requests pipelining in HTTP/1.1 ({@link Protocol#HTTP_JSON} or {@link Protocol#HTTP_VPACK}).
+ *
+ * @param pipelining {@code true} if enabled
+ * @return {@link ArangoDB.Builder}
+ */
+ public Builder pipelining(final Boolean pipelining) {
+ config.setPipelining(pipelining);
+ return this;
+ }
+
/**
* Sets the maximum number of connections the built in connection pool will open per host.
*
diff --git a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java
index 047d55280..832c8862d 100644
--- a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java
+++ b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java
@@ -21,6 +21,7 @@ public interface ArangoConfigProperties {
String KEY_USE_SSL = "useSsl";
String KEY_VERIFY_HOST = "verifyHost";
String KEY_CHUNK_SIZE = "chunkSize";
+ String KEY_PIPELINING = "pipelining";
String KEY_MAX_CONNECTIONS = "maxConnections";
String KEY_CONNECTION_TTL = "connectionTtl";
String KEY_KEEP_ALIVE_INTERVAL = "keepAliveInterval";
@@ -110,6 +111,10 @@ default Optional getChunkSize() {
return Optional.empty();
}
+ default Optional getPipelining() {
+ return Optional.empty();
+ }
+
default Optional getMaxConnections() {
return Optional.empty();
}
diff --git a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java
index b08c045da..25448187c 100644
--- a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java
+++ b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java
@@ -50,6 +50,7 @@ public final class ArangoDefaults {
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;
+ public static final Boolean DEFAULT_PIPELINING = false;
public static final Boolean DEFAULT_ACQUIRE_HOST_LIST = false;
public static final Integer DEFAULT_ACQUIRE_HOST_LIST_INTERVAL = 60 * 60 * 1000; // hour
public static final LoadBalancingStrategy DEFAULT_LOAD_BALANCING_STRATEGY = LoadBalancingStrategy.NONE;
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 f38903532..f95e0a4e2 100644
--- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java
+++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java
@@ -33,6 +33,7 @@ public class ArangoConfig {
private SSLContext sslContext;
private Boolean verifyHost;
private Integer chunkSize;
+ private Boolean pipelining;
private Integer maxConnections;
private Long connectionTtl;
private Integer keepAliveInterval;
@@ -70,6 +71,7 @@ public void loadProperties(final ArangoConfigProperties properties) {
useSsl = properties.getUseSsl().orElse(ArangoDefaults.DEFAULT_USE_SSL);
verifyHost = properties.getVerifyHost().orElse(ArangoDefaults.DEFAULT_VERIFY_HOST);
chunkSize = properties.getChunkSize().orElse(ArangoDefaults.DEFAULT_CHUNK_SIZE);
+ pipelining = properties.getPipelining().orElse(ArangoDefaults.DEFAULT_PIPELINING);
// FIXME: make maxConnections field Optional
maxConnections = properties.getMaxConnections().orElse(null);
// FIXME: make connectionTtl field Optional
@@ -173,6 +175,14 @@ public void setChunkSize(Integer chunkSize) {
this.chunkSize = chunkSize;
}
+ public Boolean getPipelining() {
+ return pipelining;
+ }
+
+ public void setPipelining(Boolean pipelining) {
+ this.pipelining = pipelining;
+ }
+
public Integer getMaxConnections() {
if (maxConnections == null) {
maxConnections = getDefaultMaxConnections();
diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java
index e4502d3d8..f7d865f81 100644
--- a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java
+++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java
@@ -119,6 +119,11 @@ public Optional getChunkSize() {
return Optional.ofNullable(getProperty(KEY_CHUNK_SIZE)).map(Integer::valueOf);
}
+ @Override
+ public Optional getPipelining() {
+ return Optional.ofNullable(getProperty(KEY_PIPELINING)).map(Boolean::valueOf);
+ }
+
@Override
public Optional getMaxConnections() {
return Optional.ofNullable(getProperty(KEY_MAX_CONNECTIONS)).map(Integer::valueOf);
diff --git a/core/src/main/java/com/arangodb/internal/net/Communication.java b/core/src/main/java/com/arangodb/internal/net/Communication.java
index 0309cd04c..1bbe59f25 100644
--- a/core/src/main/java/com/arangodb/internal/net/Communication.java
+++ b/core/src/main/java/com/arangodb/internal/net/Communication.java
@@ -50,7 +50,9 @@ public CompletableFuture executeAsync(final InternalRequest re
private CompletableFuture executeAsync(final InternalRequest request, final HostHandle hostHandle, final Host host, final int attemptCount) {
long reqId = reqCount.getAndIncrement();
- return doExecuteAsync(request, hostHandle, host, attemptCount, host.connection(), reqId);
+ return host.connection().thenCompose(c ->
+ doExecuteAsync(request, hostHandle, host, attemptCount, c, reqId)
+ .whenComplete((r, t) -> host.release(c)));
}
private CompletableFuture doExecuteAsync(
diff --git a/core/src/main/java/com/arangodb/internal/net/ConnectionPool.java b/core/src/main/java/com/arangodb/internal/net/ConnectionPool.java
index 91c12bb02..1fdb5130b 100644
--- a/core/src/main/java/com/arangodb/internal/net/ConnectionPool.java
+++ b/core/src/main/java/com/arangodb/internal/net/ConnectionPool.java
@@ -23,6 +23,7 @@
import com.arangodb.config.HostDescription;
import java.io.Closeable;
+import java.util.concurrent.CompletableFuture;
/**
* @author Mark Vollmary
@@ -31,7 +32,9 @@ public interface ConnectionPool extends Closeable {
Connection createConnection(final HostDescription host);
- Connection connection();
+ CompletableFuture connection();
+
+ void release(final Connection connection);
void setJwt(String jwt);
diff --git a/core/src/main/java/com/arangodb/internal/net/ConnectionPoolImpl.java b/core/src/main/java/com/arangodb/internal/net/ConnectionPoolImpl.java
index 8337a67bf..f85c456ce 100644
--- a/core/src/main/java/com/arangodb/internal/net/ConnectionPoolImpl.java
+++ b/core/src/main/java/com/arangodb/internal/net/ConnectionPoolImpl.java
@@ -23,22 +23,28 @@
import com.arangodb.ArangoDBException;
import com.arangodb.config.HostDescription;
import com.arangodb.internal.config.ArangoConfig;
+import com.arangodb.internal.util.AsyncQueue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
/**
* @author Mark Vollmary
*/
public class ConnectionPoolImpl implements ConnectionPool {
+ public static final int HTTP1_PIPELINING_LIMIT = 10;
+ public static final int HTTP2_STREAMS = 32; // hard-coded, see BTS-2049
+
+ private final AsyncQueue slots = new AsyncQueue<>();
private final HostDescription host;
private final ArangoConfig config;
private final int maxConnections;
private final List connections;
private final ConnectionFactory factory;
- private int current;
+ private final int maxSlots;
private volatile String jwt = null;
private boolean closed = false;
@@ -49,7 +55,14 @@ public ConnectionPoolImpl(final HostDescription host, final ArangoConfig config,
this.maxConnections = config.getMaxConnections();
this.factory = factory;
connections = new ArrayList<>();
- current = 0;
+ switch (config.getProtocol()) {
+ case HTTP_JSON:
+ case HTTP_VPACK:
+ maxSlots = config.getPipelining() ? HTTP1_PIPELINING_LIMIT : 1;
+ break;
+ default:
+ maxSlots = HTTP2_STREAMS;
+ }
}
@Override
@@ -60,23 +73,25 @@ public Connection createConnection(final HostDescription host) {
}
@Override
- public synchronized Connection connection() {
+ public synchronized CompletableFuture connection() {
if (closed) {
throw new ArangoDBException("Connection pool already closed!");
}
- final Connection connection;
-
if (connections.size() < maxConnections) {
- connection = createConnection(host);
+ Connection connection = createConnection(host);
connections.add(connection);
- current++;
- } else {
- final int index = Math.floorMod(current++, connections.size());
- connection = connections.get(index);
+ for (int i = 0; i < maxSlots; i++) {
+ slots.offer((connection));
+ }
}
- return connection;
+ return slots.poll();
+ }
+
+ @Override
+ public void release(Connection connection) {
+ slots.offer(connection);
}
@Override
@@ -101,7 +116,7 @@ public synchronized void close() throws IOException {
@Override
public String toString() {
return "ConnectionPoolImpl [host=" + host + ", maxConnections=" + maxConnections + ", connections="
- + connections.size() + ", current=" + current + ", factory=" + factory.getClass().getSimpleName() + "]";
+ + connections.size() + ", factory=" + factory.getClass().getSimpleName() + "]";
}
}
diff --git a/core/src/main/java/com/arangodb/internal/net/Host.java b/core/src/main/java/com/arangodb/internal/net/Host.java
index 07fd3c6ee..08f49516d 100644
--- a/core/src/main/java/com/arangodb/internal/net/Host.java
+++ b/core/src/main/java/com/arangodb/internal/net/Host.java
@@ -24,6 +24,7 @@
import com.arangodb.config.HostDescription;
import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
/**
* @author Mark Vollmary
@@ -33,7 +34,9 @@ public interface Host {
HostDescription getDescription();
- Connection connection();
+ CompletableFuture connection();
+
+ void release(Connection c);
void closeOnError();
@@ -44,5 +47,4 @@ public interface Host {
void setMarkforDeletion(boolean markforDeletion);
void setJwt(String jwt);
-
}
diff --git a/core/src/main/java/com/arangodb/internal/net/HostImpl.java b/core/src/main/java/com/arangodb/internal/net/HostImpl.java
index 1ef822618..af2722418 100644
--- a/core/src/main/java/com/arangodb/internal/net/HostImpl.java
+++ b/core/src/main/java/com/arangodb/internal/net/HostImpl.java
@@ -24,6 +24,7 @@
import com.arangodb.config.HostDescription;
import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
/**
* @author Mark Vollmary
@@ -51,10 +52,15 @@ public HostDescription getDescription() {
}
@Override
- public Connection connection() {
+ public CompletableFuture connection() {
return connectionPool.connection();
}
+ @Override
+ public void release(Connection c) {
+ connectionPool.release(c);
+ }
+
@Override
public void closeOnError() {
try {
diff --git a/core/src/main/java/com/arangodb/internal/util/AsyncQueue.java b/core/src/main/java/com/arangodb/internal/util/AsyncQueue.java
new file mode 100644
index 000000000..999bf2816
--- /dev/null
+++ b/core/src/main/java/com/arangodb/internal/util/AsyncQueue.java
@@ -0,0 +1,30 @@
+package com.arangodb.internal.util;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+
+public class AsyncQueue {
+ private final Queue> requests = new ArrayDeque<>();
+ private final Queue offers = new ArrayDeque<>();
+
+ public synchronized CompletableFuture poll() {
+ CompletableFuture r = new CompletableFuture<>();
+ T o = offers.poll();
+ if (o != null) {
+ r.complete(o);
+ } else {
+ requests.add(r);
+ }
+ return r;
+ }
+
+ public synchronized void offer(T o) {
+ CompletableFuture r = requests.poll();
+ if (r != null) {
+ r.complete(o);
+ } else {
+ offers.add(o);
+ }
+ }
+}
diff --git a/docker/start_db.sh b/docker/start_db.sh
index 4c0c2e9a2..e8c58ebcd 100755
--- a/docker/start_db.sh
+++ b/docker/start_db.sh
@@ -66,7 +66,7 @@ docker run -d \
--starter.address="${GW}" \
--docker.image="${DOCKER_IMAGE}" \
--starter.local --starter.mode=${STARTER_MODE} --all.log.level=debug --all.log.output=+ --log.verbose \
- --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true
+ --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true --all.server.maximal-threads=128
wait_server() {
diff --git a/driver/pom.xml b/driver/pom.xml
index 2d31dfb0c..542b239a5 100644
--- a/driver/pom.xml
+++ b/driver/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
arangodb-java-driver
diff --git a/http-protocol/pom.xml b/http-protocol/pom.xml
index d9b538f46..2bd8fc87c 100644
--- a/http-protocol/pom.xml
+++ b/http-protocol/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
http-protocol
diff --git a/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java b/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java
index 87a47c760..683bb954d 100644
--- a/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java
+++ b/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java
@@ -63,6 +63,9 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import static com.arangodb.internal.net.ConnectionPoolImpl.HTTP1_PIPELINING_LIMIT;
+import static com.arangodb.internal.net.ConnectionPoolImpl.HTTP2_STREAMS;
+
/**
* @author Mark Vollmary
@@ -88,7 +91,6 @@ private static String getUserAgent() {
}
HttpConnection(final ArangoConfig config, final HostDescription host, final HttpProtocolConfig protocolConfig) {
- super();
Protocol protocol = config.getProtocol();
ContentType contentType = ContentTypeFactory.of(protocol);
if (contentType == ContentType.VPACK) {
@@ -148,7 +150,9 @@ private static String getUserAgent() {
.setLogActivity(true)
.setKeepAlive(true)
.setTcpKeepAlive(true)
- .setPipelining(true)
+ .setPipelining(config.getPipelining())
+ .setPipeliningLimit(HTTP1_PIPELINING_LIMIT)
+ .setHttp2MultiplexingLimit(HTTP2_STREAMS)
.setReuseAddress(true)
.setReusePort(true)
.setHttp2ClearTextUpgrade(false)
@@ -273,7 +277,7 @@ public CompletableFuture executeAsync(@UnstableApi final Inter
return rfuture;
}
- public void doExecute(@UnstableApi final InternalRequest request, @UnstableApi final CompletableFuture rfuture) {
+ private void doExecute(@UnstableApi final InternalRequest request, @UnstableApi final CompletableFuture rfuture) {
String path = buildUrl(request);
HttpRequest httpRequest = client
.request(requestTypeToHttpMethod(request.getRequestType()), path)
diff --git a/jackson-serde-json/pom.xml b/jackson-serde-json/pom.xml
index 61b9acd55..816d6eefc 100644
--- a/jackson-serde-json/pom.xml
+++ b/jackson-serde-json/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
jackson-serde-json
diff --git a/jackson-serde-vpack/pom.xml b/jackson-serde-vpack/pom.xml
index 81a581480..14d2cafc5 100644
--- a/jackson-serde-vpack/pom.xml
+++ b/jackson-serde-vpack/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
jackson-serde-vpack
diff --git a/jsonb-serde/pom.xml b/jsonb-serde/pom.xml
index 5cb72c2a1..e3d23beae 100644
--- a/jsonb-serde/pom.xml
+++ b/jsonb-serde/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
jsonb-serde
diff --git a/pom.xml b/pom.xml
index 3493461af..d1c2a81f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.arangodb
arangodb-java-driver-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
2016
release-parent
diff --git a/release-parent/pom.xml b/release-parent/pom.xml
index e0846a551..502df1b43 100644
--- a/release-parent/pom.xml
+++ b/release-parent/pom.xml
@@ -6,7 +6,7 @@
com.arangodb
arangodb-java-driver-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
pom
diff --git a/shaded/pom.xml b/shaded/pom.xml
index 76e43d4d3..6a4147cd1 100644
--- a/shaded/pom.xml
+++ b/shaded/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
arangodb-java-driver-shaded
diff --git a/test-functional/pom.xml b/test-functional/pom.xml
index 71bdae4ec..a8fd16797 100644
--- a/test-functional/pom.xml
+++ b/test-functional/pom.xml
@@ -8,7 +8,7 @@
../test-parent
com.arangodb
test-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
test-functional
diff --git a/test-functional/src/test/java/com/arangodb/UserAgentTest.java b/test-functional/src/test/java/com/arangodb/UserAgentTest.java
index aa794f069..9af38f28a 100644
--- a/test-functional/src/test/java/com/arangodb/UserAgentTest.java
+++ b/test-functional/src/test/java/com/arangodb/UserAgentTest.java
@@ -10,7 +10,7 @@
class UserAgentTest extends BaseJunit5 {
- private static final String EXPECTED_VERSION = "7.18.0";
+ private static final String EXPECTED_VERSION = "7.19.0-SNAPSHOT";
private static final boolean SHADED = Boolean.parseBoolean(System.getProperty("shaded"));
diff --git a/test-functional/src/test/java/com/arangodb/internal/HostHandlerTest.java b/test-functional/src/test/java/com/arangodb/internal/HostHandlerTest.java
index 674c14851..92061a62b 100644
--- a/test-functional/src/test/java/com/arangodb/internal/HostHandlerTest.java
+++ b/test-functional/src/test/java/com/arangodb/internal/HostHandlerTest.java
@@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
@@ -44,10 +45,15 @@ public Connection createConnection(HostDescription host) {
}
@Override
- public Connection connection() {
+ public CompletableFuture connection() {
return null;
}
+ @Override
+ public void release(Connection connection) {
+
+ }
+
@Override
public void setJwt(String jwt) {
diff --git a/test-functional/src/test/resources/simplelogger.properties b/test-functional/src/test/resources/simplelogger.properties
index c375e20ef..a2a4ce6d5 100644
--- a/test-functional/src/test/resources/simplelogger.properties
+++ b/test-functional/src/test/resources/simplelogger.properties
@@ -10,3 +10,5 @@ org.slf4j.simpleLogger.defaultLogLevel=info
#org.slf4j.simpleLogger.log.com.arangodb.internal.serde.JacksonUtils=debug
#org.slf4j.simpleLogger.log.com.arangodb.internal.net.Communication=debug
#org.slf4j.simpleLogger.log.com.arangodb.internal.serde.InternalSerdeImpl=debug
+#org.slf4j.simpleLogger.log.io.netty.handler.logging.LoggingHandler=debug
+#org.slf4j.simpleLogger.log.io.netty.handler.codec.http2.Http2FrameLogger=debug
diff --git a/test-non-functional/pom.xml b/test-non-functional/pom.xml
index bf7219a25..a10f0aaa9 100644
--- a/test-non-functional/pom.xml
+++ b/test-non-functional/pom.xml
@@ -8,7 +8,7 @@
../test-parent
com.arangodb
test-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
test-non-functional
diff --git a/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java b/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java
new file mode 100644
index 000000000..402450ce0
--- /dev/null
+++ b/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java
@@ -0,0 +1,111 @@
+package concurrency;
+
+import com.arangodb.*;
+import com.arangodb.config.ArangoConfigProperties;
+import com.arangodb.internal.net.ConnectionPoolImpl;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import util.TestUtils;
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static org.awaitility.Awaitility.await;
+
+public class ConnectionLoadBalanceTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionLoadBalanceTest.class);
+
+ public static Stream configs() {
+ return Stream.of(
+// FIXME: DE-1017
+// new Config(Protocol.VST, 1),
+// new Config(Protocol.VST, 2),
+ new Config(Protocol.HTTP_JSON, 10),
+ new Config(Protocol.HTTP_JSON, 20),
+ new Config(Protocol.HTTP2_JSON, 1),
+ new Config(Protocol.HTTP2_JSON, 2)
+ ).map(Arguments::of);
+ }
+
+ // Test the requests load balancing across different connections, when all the slots except 1 are busy
+ @MethodSource("configs")
+ @ParameterizedTest
+ void loadBalanceToAvailableSlots(Config cfg) throws InterruptedException {
+ doTestLoadBalance(cfg, 1);
+ }
+
+ // Test the requests load balancing across different connections, when all the slots are busy
+ @MethodSource("configs")
+ @ParameterizedTest
+ void loadBalanceAllBusy(Config cfg) throws InterruptedException {
+ doTestLoadBalance(cfg, 2);
+ }
+
+ void doTestLoadBalance(Config cfg, int sleepCycles) throws InterruptedException {
+ int longTasksCount = cfg.maxStreams() * cfg.maxConnections * sleepCycles - 1;
+ int shortTasksCount = 10;
+ long sleepDuration = 2;
+
+ ArangoDatabaseAsync db = new ArangoDB.Builder()
+ .loadProperties(ArangoConfigProperties.fromFile())
+ .protocol(cfg.protocol)
+ .serde(TestUtils.createSerde(cfg.protocol))
+ .maxConnections(cfg.maxConnections)
+ .build().async().db();
+
+ CompletableFuture longRunningTasks = CompletableFuture.allOf(
+ IntStream.range(0, longTasksCount)
+ .mapToObj(__ ->
+ db.query("RETURN SLEEP(@duration)", Void.class, Map.of("duration", sleepDuration)))
+ .toArray(CompletableFuture[]::new)
+ );
+
+ Thread.sleep(100);
+
+ CompletableFuture shortRunningTasks = CompletableFuture.allOf(
+ IntStream.range(0, shortTasksCount)
+ .mapToObj(__ -> db.getVersion())
+ .toArray(CompletableFuture[]::new)
+ );
+
+ LOGGER.debug("awaiting...");
+
+ await()
+ .timeout(Duration.ofSeconds(sleepDuration * sleepCycles - 1L))
+ .until(shortRunningTasks::isDone);
+
+ LOGGER.debug("completed shortRunningTasks");
+
+ // join exceptional completions
+ shortRunningTasks.join();
+
+ await()
+ .timeout(Duration.ofSeconds(sleepDuration * sleepCycles + 1L))
+ .until(longRunningTasks::isDone);
+
+ LOGGER.debug("completed longRunningTasks");
+
+ // join exceptional completions
+ longRunningTasks.join();
+
+ db.arango().shutdown();
+ }
+
+ private record Config(
+ Protocol protocol,
+ int maxConnections
+ ) {
+ int maxStreams() {
+ return switch (protocol) {
+ case HTTP_JSON, HTTP_VPACK -> 1;
+ default -> ConnectionPoolImpl.HTTP2_STREAMS;
+ };
+ }
+ }
+}
diff --git a/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java b/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java
index 1a0407a4c..4cac7a647 100644
--- a/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java
+++ b/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java
@@ -23,6 +23,7 @@ public final class ArangoConfigPropertiesMPImpl implements ArangoConfigPropertie
private Optional useSsl;
private Optional verifyHost;
private Optional chunkSize;
+ private Optional pipelining;
private Optional maxConnections;
private Optional connectionTtl;
private Optional keepAliveInterval;
@@ -80,6 +81,11 @@ public Optional getChunkSize() {
return chunkSize;
}
+ @Override
+ public Optional getPipelining() {
+ return pipelining;
+ }
+
@Override
public Optional getMaxConnections() {
return maxConnections;
@@ -140,12 +146,12 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArangoConfigPropertiesMPImpl that = (ArangoConfigPropertiesMPImpl) o;
- return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples) && Objects.equals(compression, that.compression) && Objects.equals(compressionThreshold, that.compressionThreshold) && Objects.equals(compressionLevel, that.compressionLevel) && Objects.equals(serdeProviderClass, that.serdeProviderClass);
+ return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(pipelining, that.pipelining) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples) && Objects.equals(compression, that.compression) && Objects.equals(compressionThreshold, that.compressionThreshold) && Objects.equals(compressionLevel, that.compressionLevel) && Objects.equals(serdeProviderClass, that.serdeProviderClass);
}
@Override
public int hashCode() {
- return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples, compression, compressionThreshold, compressionLevel, serdeProviderClass);
+ return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, pipelining, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples, compression, compressionThreshold, compressionLevel, serdeProviderClass);
}
@Override
@@ -160,6 +166,7 @@ public String toString() {
", useSsl=" + useSsl +
", verifyHost=" + verifyHost +
", chunkSize=" + chunkSize +
+ ", pipelining=" + pipelining +
", maxConnections=" + maxConnections +
", connectionTtl=" + connectionTtl +
", keepAliveInterval=" + keepAliveInterval +
diff --git a/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java b/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java
index 3ff81bd04..5a8f861ef 100644
--- a/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java
+++ b/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java
@@ -25,6 +25,7 @@ private void checkResult(ArangoConfigProperties config) {
assertThat(config.getUseSsl()).isEmpty();
assertThat(config.getVerifyHost()).isEmpty();
assertThat(config.getChunkSize()).isEmpty();
+ assertThat(config.getPipelining()).isEmpty();
assertThat(config.getMaxConnections()).isNotPresent();
assertThat(config.getConnectionTtl()).isNotPresent();
assertThat(config.getKeepAliveInterval()).isNotPresent();
diff --git a/test-non-functional/src/test/java/mp/ConfigMPTest.java b/test-non-functional/src/test/java/mp/ConfigMPTest.java
index 4a7aaa993..5d5f605e3 100644
--- a/test-non-functional/src/test/java/mp/ConfigMPTest.java
+++ b/test-non-functional/src/test/java/mp/ConfigMPTest.java
@@ -23,6 +23,7 @@ class ConfigMPTest {
private final Boolean useSsl = true;
private final Boolean verifyHost = false;
private final Integer vstChunkSize = 1234;
+ private final Boolean pipelining = true;
private final Integer maxConnections = 123;
private final Long connectionTtl = 12345L;
private final Integer keepAliveInterval = 123456;
@@ -58,6 +59,7 @@ private void checkResult(ArangoConfigProperties config) {
assertThat(config.getUseSsl()).hasValue(useSsl);
assertThat(config.getVerifyHost()).hasValue(verifyHost);
assertThat(config.getChunkSize()).hasValue(vstChunkSize);
+ assertThat(config.getPipelining()).hasValue(pipelining);
assertThat(config.getMaxConnections())
.isPresent()
.hasValue(maxConnections);
diff --git a/test-non-functional/src/test/resources/arangodb-config-test.properties b/test-non-functional/src/test/resources/arangodb-config-test.properties
index ef25aaf11..1d5e675af 100644
--- a/test-non-functional/src/test/resources/arangodb-config-test.properties
+++ b/test-non-functional/src/test/resources/arangodb-config-test.properties
@@ -7,6 +7,7 @@ adb.timeout=9876
adb.useSsl=true
adb.verifyHost=false
adb.chunkSize=1234
+adb.pipelining=true
adb.maxConnections=123
adb.connectionTtl=12345
adb.keepAliveInterval=123456
diff --git a/test-non-functional/src/test/resources/simplelogger.properties b/test-non-functional/src/test/resources/simplelogger.properties
index 7649bd6c7..d992c3d63 100644
--- a/test-non-functional/src/test/resources/simplelogger.properties
+++ b/test-non-functional/src/test/resources/simplelogger.properties
@@ -9,3 +9,5 @@ org.slf4j.simpleLogger.showShortLogName=false
org.slf4j.simpleLogger.defaultLogLevel=info
#org.slf4j.simpleLogger.log.com.arangodb.internal.serde.JacksonUtils=debug
#org.slf4j.simpleLogger.log.com.arangodb.internal.net.Communication=debug
+#org.slf4j.simpleLogger.log.io.netty.handler.logging.LoggingHandler=debug
+#org.slf4j.simpleLogger.log.io.netty.handler.codec.http2.Http2FrameLogger=debug
diff --git a/test-parent/pom.xml b/test-parent/pom.xml
index b68b5c4d1..d582c6f5b 100644
--- a/test-parent/pom.xml
+++ b/test-parent/pom.xml
@@ -7,7 +7,7 @@
com.arangodb
arangodb-java-driver-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
pom
@@ -60,6 +60,11 @@
assertj-core
test
+
+ org.awaitility
+ awaitility
+ test
+
@@ -93,6 +98,12 @@
assertj-core
3.25.3
+
+ org.awaitility
+ awaitility
+ 4.2.1
+ test
+
com.tngtech.archunit
archunit-junit5
diff --git a/test-perf/pom.xml b/test-perf/pom.xml
index 4e31b0ab1..3ab88b158 100644
--- a/test-perf/pom.xml
+++ b/test-perf/pom.xml
@@ -7,7 +7,7 @@
../test-parent
com.arangodb
test-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
test-perf
diff --git a/test-resilience/pom.xml b/test-resilience/pom.xml
index bd7963bbc..a6b8f4f56 100644
--- a/test-resilience/pom.xml
+++ b/test-resilience/pom.xml
@@ -6,7 +6,7 @@
../test-parent
com.arangodb
test-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
4.0.0
@@ -29,12 +29,6 @@
2.1.7
test
-
- org.awaitility
- awaitility
- 4.2.0
- test
-
ch.qos.logback
logback-classic
diff --git a/tutorial/gradle/build.gradle b/tutorial/gradle/build.gradle
index cb34d15d7..ff468c6db 100644
--- a/tutorial/gradle/build.gradle
+++ b/tutorial/gradle/build.gradle
@@ -12,7 +12,7 @@ repositories {
}
dependencies {
- implementation 'com.arangodb:arangodb-java-driver:7.18.0'
+ implementation 'com.arangodb:arangodb-java-driver:7.19.0-SNAPSHOT'
}
ext {
diff --git a/tutorial/maven/pom.xml b/tutorial/maven/pom.xml
index e5e32c7c2..7e33fd350 100644
--- a/tutorial/maven/pom.xml
+++ b/tutorial/maven/pom.xml
@@ -19,7 +19,7 @@
com.arangodb
arangodb-java-driver
- 7.18.0
+ 7.19.0-SNAPSHOT
diff --git a/vst-protocol/pom.xml b/vst-protocol/pom.xml
index 94b176118..3aedd968d 100644
--- a/vst-protocol/pom.xml
+++ b/vst-protocol/pom.xml
@@ -8,7 +8,7 @@
../release-parent
com.arangodb
release-parent
- 7.18.0
+ 7.19.0-SNAPSHOT
vst-protocol