Skip to content

Commit f3429b2

Browse files
authored
Feature/vst keep alive (#370)
* VST keepAliveScheduler * VST keepAlive interval configuration
1 parent f75985b commit f3429b2

File tree

8 files changed

+207
-25
lines changed

8 files changed

+207
-25
lines changed

src/main/java/com/arangodb/ArangoDB.java

+39-4
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,25 @@
2020

2121
package com.arangodb;
2222

23-
import com.arangodb.entity.*;
23+
import com.arangodb.entity.ArangoDBEngine;
24+
import com.arangodb.entity.ArangoDBVersion;
25+
import com.arangodb.entity.LoadBalancingStrategy;
26+
import com.arangodb.entity.LogEntity;
27+
import com.arangodb.entity.LogLevelEntity;
28+
import com.arangodb.entity.Permissions;
29+
import com.arangodb.entity.ServerRole;
30+
import com.arangodb.entity.UserEntity;
2431
import com.arangodb.internal.ArangoContext;
2532
import com.arangodb.internal.ArangoDBImpl;
2633
import com.arangodb.internal.ArangoDefaults;
2734
import com.arangodb.internal.InternalArangoDBBuilder;
2835
import com.arangodb.internal.http.HttpCommunication;
2936
import com.arangodb.internal.http.HttpConnectionFactory;
30-
import com.arangodb.internal.net.*;
37+
import com.arangodb.internal.net.ConnectionFactory;
38+
import com.arangodb.internal.net.Host;
39+
import com.arangodb.internal.net.HostHandle;
40+
import com.arangodb.internal.net.HostHandler;
41+
import com.arangodb.internal.net.HostResolver;
3142
import com.arangodb.internal.util.ArangoDeserializerImpl;
3243
import com.arangodb.internal.util.ArangoSerializationFactory;
3344
import com.arangodb.internal.util.ArangoSerializerImpl;
@@ -42,7 +53,18 @@
4253
import com.arangodb.util.ArangoDeserializer;
4354
import com.arangodb.util.ArangoSerialization;
4455
import com.arangodb.util.ArangoSerializer;
45-
import com.arangodb.velocypack.*;
56+
import com.arangodb.velocypack.VPack;
57+
import com.arangodb.velocypack.VPackAnnotationFieldFilter;
58+
import com.arangodb.velocypack.VPackAnnotationFieldNaming;
59+
import com.arangodb.velocypack.VPackDeserializer;
60+
import com.arangodb.velocypack.VPackInstanceCreator;
61+
import com.arangodb.velocypack.VPackJsonDeserializer;
62+
import com.arangodb.velocypack.VPackJsonSerializer;
63+
import com.arangodb.velocypack.VPackModule;
64+
import com.arangodb.velocypack.VPackParser;
65+
import com.arangodb.velocypack.VPackParserModule;
66+
import com.arangodb.velocypack.VPackSerializer;
67+
import com.arangodb.velocypack.ValueType;
4668
import com.arangodb.velocystream.Request;
4769
import com.arangodb.velocystream.Response;
4870
import org.apache.http.client.HttpRequestRetryHandler;
@@ -248,6 +270,19 @@ public Builder connectionTtl(final Long connectionTtl) {
248270
return this;
249271
}
250272

273+
/**
274+
* Set the keep-alive interval for VST connections. If set, every VST connection will perform a no-op request every
275+
* {@code keepAliveInterval} seconds, to avoid to be closed due to inactivity by the server (or by the external
276+
* environment, eg. firewall, intermediate routers, operating system).
277+
*
278+
* @param keepAliveInterval interval in seconds
279+
* @return {@link ArangoDB.Builder}
280+
*/
281+
public Builder keepAliveInterval(final Integer keepAliveInterval) {
282+
setKeepAliveInterval(keepAliveInterval);
283+
return this;
284+
}
285+
251286
/**
252287
* Whether or not the driver should acquire a list of available coordinators in an ArangoDB cluster or a single
253288
* server with active failover.
@@ -600,7 +635,7 @@ public synchronized ArangoDB build() {
600635
final int max = maxConnections != null ? Math.max(1, maxConnections) : protocolMaxConnections;
601636

602637
final ConnectionFactory connectionFactory = (protocol == null || Protocol.VST == protocol)
603-
? new VstConnectionFactorySync(host, timeout, connectionTtl, useSsl, sslContext)
638+
? new VstConnectionFactorySync(host, timeout, connectionTtl, keepAliveInterval, useSsl, sslContext)
604639
: new HttpConnectionFactory(timeout, user, password, useSsl, sslContext, hostnameVerifier, custom,
605640
protocol, connectionTtl, httpCookieSpec, httpRequestRetryHandler);
606641

src/main/java/com/arangodb/async/ArangoDBAsync.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@
2626
import com.arangodb.async.internal.ArangoDBAsyncImpl;
2727
import com.arangodb.async.internal.velocystream.VstCommunicationAsync;
2828
import com.arangodb.async.internal.velocystream.VstConnectionFactoryAsync;
29-
import com.arangodb.entity.*;
29+
import com.arangodb.entity.ArangoDBVersion;
30+
import com.arangodb.entity.LoadBalancingStrategy;
31+
import com.arangodb.entity.LogEntity;
32+
import com.arangodb.entity.LogLevelEntity;
33+
import com.arangodb.entity.Permissions;
34+
import com.arangodb.entity.ServerRole;
35+
import com.arangodb.entity.UserEntity;
3036
import com.arangodb.internal.ArangoContext;
3137
import com.arangodb.internal.ArangoDefaults;
3238
import com.arangodb.internal.InternalArangoDBBuilder;
@@ -45,7 +51,18 @@
4551
import com.arangodb.util.ArangoDeserializer;
4652
import com.arangodb.util.ArangoSerialization;
4753
import com.arangodb.util.ArangoSerializer;
48-
import com.arangodb.velocypack.*;
54+
import com.arangodb.velocypack.VPack;
55+
import com.arangodb.velocypack.VPackAnnotationFieldFilter;
56+
import com.arangodb.velocypack.VPackAnnotationFieldNaming;
57+
import com.arangodb.velocypack.VPackDeserializer;
58+
import com.arangodb.velocypack.VPackInstanceCreator;
59+
import com.arangodb.velocypack.VPackJsonDeserializer;
60+
import com.arangodb.velocypack.VPackJsonSerializer;
61+
import com.arangodb.velocypack.VPackModule;
62+
import com.arangodb.velocypack.VPackParser;
63+
import com.arangodb.velocypack.VPackParserModule;
64+
import com.arangodb.velocypack.VPackSerializer;
65+
import com.arangodb.velocypack.ValueType;
4966
import com.arangodb.velocystream.Request;
5067
import com.arangodb.velocystream.Response;
5168

@@ -408,6 +425,19 @@ public Builder connectionTtl(final Long connectionTtl) {
408425
return this;
409426
}
410427

428+
/**
429+
* Set the keep-alive interval for VST connections. If set, every VST connection will perform a no-op request every
430+
* {@code keepAliveInterval} seconds, to avoid to be closed due to inactivity by the server (or by the external
431+
* environment, eg. firewall, intermediate routers, operating system).
432+
*
433+
* @param keepAliveInterval interval in seconds
434+
* @return {@link ArangoDBAsync.Builder}
435+
*/
436+
public Builder keepAliveInterval(final Integer keepAliveInterval) {
437+
setKeepAliveInterval(keepAliveInterval);
438+
return this;
439+
}
440+
411441
/**
412442
* Whether or not the driver should acquire a list of available coordinators in an ArangoDB cluster or a single
413443
* server with active failover.
@@ -746,7 +776,7 @@ public synchronized ArangoDBAsync build() {
746776
final int max = maxConnections != null ? Math.max(1, maxConnections)
747777
: ArangoDefaults.MAX_CONNECTIONS_VST_DEFAULT;
748778
final ConnectionFactory connectionFactory = new VstConnectionFactoryAsync(host, timeout, connectionTtl,
749-
useSsl, sslContext);
779+
keepAliveInterval, useSsl, sslContext);
750780
final HostResolver hostResolver = createHostResolver(createHostList(max, connectionFactory), max,
751781
connectionFactory);
752782
final HostHandler hostHandler = createHostHandler(hostResolver);

src/main/java/com/arangodb/async/internal/velocystream/VstConnectionAsync.java

+17-5
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@
3434
/**
3535
* @author Mark Vollmary
3636
*/
37-
public class VstConnectionAsync extends VstConnection {
37+
public class VstConnectionAsync extends VstConnection<CompletableFuture<Message>> {
3838

39-
private VstConnectionAsync(final HostDescription host, final Integer timeout, final Long ttl, final Boolean useSsl,
40-
final SSLContext sslContext, final MessageStore messageStore) {
41-
super(host, timeout, ttl, useSsl, sslContext, messageStore);
39+
private VstConnectionAsync(final HostDescription host, final Integer timeout, final Long ttl, final Integer keepAliveInterval,
40+
final Boolean useSsl, final SSLContext sslContext, final MessageStore messageStore) {
41+
super(host, timeout, ttl, keepAliveInterval, useSsl, sslContext, messageStore);
4242
}
4343

44+
@Override
4445
public synchronized CompletableFuture<Message> write(final Message message, final Collection<Chunk> chunks) {
4546
final CompletableFuture<Message> future = new CompletableFuture<>();
4647
final FutureTask<Message> task = new FutureTask<>(() -> {
@@ -56,12 +57,18 @@ public synchronized CompletableFuture<Message> write(final Message message, fina
5657
return future;
5758
}
5859

60+
@Override
61+
protected void doKeepAlive() {
62+
sendKeepAlive().join();
63+
}
64+
5965
public static class Builder {
6066

6167
private MessageStore messageStore;
6268
private HostDescription host;
6369
private Integer timeout;
6470
private Long ttl;
71+
private Integer keepAliveInterval;
6572
private Boolean useSsl;
6673
private SSLContext sslContext;
6774

@@ -89,6 +96,11 @@ public Builder ttl(final Long ttl) {
8996
return this;
9097
}
9198

99+
public Builder keepAliveInterval(final Integer keepAliveInterval) {
100+
this.keepAliveInterval = keepAliveInterval;
101+
return this;
102+
}
103+
92104
public Builder useSsl(final Boolean useSsl) {
93105
this.useSsl = useSsl;
94106
return this;
@@ -100,7 +112,7 @@ public Builder sslContext(final SSLContext sslContext) {
100112
}
101113

102114
public VstConnectionAsync build() {
103-
return new VstConnectionAsync(host, timeout, ttl, useSsl, sslContext, messageStore);
115+
return new VstConnectionAsync(host, timeout, ttl, keepAliveInterval, useSsl, sslContext, messageStore);
104116
}
105117
}
106118

src/main/java/com/arangodb/async/internal/velocystream/VstConnectionFactoryAsync.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ public class VstConnectionFactoryAsync implements ConnectionFactory {
3535
private final VstConnectionAsync.Builder builder;
3636

3737
public VstConnectionFactoryAsync(final HostDescription host, final Integer timeout, final Long connectionTtl,
38-
final Boolean useSsl, final SSLContext sslContext) {
38+
final Integer keepAliveInterval, final Boolean useSsl, final SSLContext sslContext) {
3939
super();
40-
builder = new VstConnectionAsync.Builder().timeout(timeout).ttl(connectionTtl).useSsl(useSsl)
40+
builder = new VstConnectionAsync.Builder().timeout(timeout).ttl(connectionTtl)
41+
.keepAliveInterval(keepAliveInterval).useSsl(useSsl)
4142
.sslContext(sslContext);
4243
}
4344

src/main/java/com/arangodb/internal/InternalArangoDBBuilder.java

+25-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,18 @@
2323
import com.arangodb.ArangoDB;
2424
import com.arangodb.ArangoDBException;
2525
import com.arangodb.entity.LoadBalancingStrategy;
26-
import com.arangodb.internal.net.*;
26+
import com.arangodb.internal.net.Connection;
27+
import com.arangodb.internal.net.ConnectionFactory;
28+
import com.arangodb.internal.net.DirtyReadHostHandler;
29+
import com.arangodb.internal.net.ExtendedHostResolver;
30+
import com.arangodb.internal.net.FallbackHostHandler;
31+
import com.arangodb.internal.net.Host;
32+
import com.arangodb.internal.net.HostDescription;
33+
import com.arangodb.internal.net.HostHandler;
34+
import com.arangodb.internal.net.HostResolver;
35+
import com.arangodb.internal.net.RandomHostHandler;
36+
import com.arangodb.internal.net.RoundRobinHostHandler;
37+
import com.arangodb.internal.net.SimpleHostResolver;
2738
import com.arangodb.internal.util.HostUtils;
2839
import com.arangodb.internal.velocypack.VPackDriverModule;
2940
import com.arangodb.util.ArangoDeserializer;
@@ -63,6 +74,7 @@ public abstract class InternalArangoDBBuilder {
6374
private static final String PROPERTY_KEY_V_STREAM_CHUNK_CONTENT_SIZE = "arangodb.chunksize";
6475
private static final String PROPERTY_KEY_MAX_CONNECTIONS = "arangodb.connections.max";
6576
private static final String PROPERTY_KEY_CONNECTION_TTL = "arangodb.connections.ttl";
77+
private static final String PROPERTY_KEEP_ALIVE_INTERVAL = "arangodb.connections.keepAlive.interval";
6678
private static final String PROPERTY_KEY_ACQUIRE_HOST_LIST = "arangodb.acquireHostList";
6779
private static final String PROPERTY_KEY_ACQUIRE_HOST_LIST_INTERVAL = "arangodb.acquireHostList.interval";
6880
private static final String PROPERTY_KEY_LOAD_BALANCING_STRATEGY = "arangodb.loadBalancingStrategy";
@@ -81,6 +93,7 @@ public abstract class InternalArangoDBBuilder {
8193
protected Integer chunksize;
8294
protected Integer maxConnections;
8395
protected Long connectionTtl;
96+
protected Integer keepAliveInterval;
8497
protected final VPack.Builder vpackBuilder;
8598
protected final VPackParser.Builder vpackParserBuilder;
8699
protected ArangoSerializer serializer;
@@ -135,6 +148,7 @@ protected void loadProperties(final Properties properties) {
135148
chunksize = loadChunkSize(properties, chunksize);
136149
maxConnections = loadMaxConnections(properties, maxConnections);
137150
connectionTtl = loadConnectionTtl(properties, connectionTtl);
151+
keepAliveInterval = loadKeepAliveInterval(properties, keepAliveInterval);
138152
acquireHostList = loadAcquireHostList(properties, acquireHostList);
139153
acquireHostListInterval = loadAcquireHostListInterval(properties, acquireHostListInterval);
140154
loadBalancingStrategy = loadLoadBalancingStrategy(properties, loadBalancingStrategy);
@@ -184,6 +198,10 @@ protected void setConnectionTtl(final Long connectionTtl) {
184198
this.connectionTtl = connectionTtl;
185199
}
186200

201+
protected void setKeepAliveInterval(final Integer keepAliveInterval) {
202+
this.keepAliveInterval = keepAliveInterval;
203+
}
204+
187205
protected void setAcquireHostList(final Boolean acquireHostList) {
188206
this.acquireHostList = acquireHostList;
189207
}
@@ -315,6 +333,12 @@ private static Long loadConnectionTtl(final Properties properties, final Long cu
315333
return ttl != null ? Long.parseLong(ttl) : null;
316334
}
317335

336+
private static Integer loadKeepAliveInterval(final Properties properties, final Integer currentValue) {
337+
final String keepAliveInterval = getProperty(properties, PROPERTY_KEEP_ALIVE_INTERVAL, currentValue,
338+
null);
339+
return keepAliveInterval != null ? Integer.parseInt(keepAliveInterval) : null;
340+
}
341+
318342
private static Boolean loadAcquireHostList(final Properties properties, final Boolean currentValue) {
319343
return Boolean.parseBoolean(getProperty(properties, PROPERTY_KEY_ACQUIRE_HOST_LIST, currentValue,
320344
ArangoDefaults.DEFAULT_ACQUIRE_HOST_LIST));

src/main/java/com/arangodb/internal/velocystream/VstConnectionFactorySync.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ public class VstConnectionFactorySync implements ConnectionFactory {
3636
private final VstConnectionSync.Builder builder;
3737

3838
public VstConnectionFactorySync(final HostDescription host, final Integer timeout, final Long connectionTtl,
39-
final Boolean useSsl, final SSLContext sslContext) {
39+
final Integer keepAliveInterval, final Boolean useSsl, final SSLContext sslContext) {
4040
super();
41-
builder = new VstConnectionSync.Builder().timeout(timeout).ttl(connectionTtl).useSsl(useSsl)
41+
builder = new VstConnectionSync.Builder().timeout(timeout).ttl(connectionTtl)
42+
.keepAliveInterval(keepAliveInterval).useSsl(useSsl)
4243
.sslContext(sslContext);
4344
}
4445

0 commit comments

Comments
 (0)