Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
L'exemple Java suivant montre comment se connecter au client Gremlin à l'aide d'une logique de reconnexion afin d'assurer la reprise après une déconnexion inattendue.
Il présente les dépendances suivantes :
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-driver</artifactId>
<version>${gremlin.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>amazon-neptune-sigv4-signer</artifactId>
<version>${sig4.signer.version}</version>
</dependency>
<dependency>
<groupId>com.evanlennick</groupId>
<artifactId>retry4j</artifactId>
<version>0.15.0</version>
</dependency>
Voici l'exemple de code :
Important
Le CallExecutor
de Retry4j n'est peut-être pas thread-safe. Envisagez de demander à chaque thread d'utiliser sa propre CallExecutor
instance ou d'utiliser une bibliothèque de nouvelles tentatives différente.
Note
L'exemple suivant a été mis à jour pour inclure l'utilisation de RequestInterceptor (). Cela a été ajouté dans la version TinkerPop 3.6.6. Avant la TinkerPop version 3.6.6, l'exemple de code utilisait HandshakeInterceptor (), qui était obsolète avec cette version.
public static void main(String args[]) {
boolean useIam = true;
// Create Gremlin cluster and traversal source
Cluster.Builder builder = Cluster.build()
.addContactPoint(System.getenv("neptuneEndpoint"))
.port(Integer.parseInt(System.getenv("neptunePort")))
.enableSsl(true)
.minConnectionPoolSize(1)
.maxConnectionPoolSize(1)
.serializer(Serializers.GRAPHBINARY_V1D0)
.reconnectInterval(2000);
if (useIam) {
builder.requestInterceptor( r -> {
try {
NeptuneNettyHttpSigV4Signer sigV4Signer =
new NeptuneNettyHttpSigV4Signer("(your region)", new DefaultAWSCredentialsProviderChain());
sigV4Signer.signRequest(r);
} catch (NeptuneSigV4SignerException e) {
throw new RuntimeException("Exception occurred while signing the request", e);
}
return r;
});
}
Cluster cluster = builder.create();
GraphTraversalSource g = AnonymousTraversalSource
.traversal()
.withRemote(DriverRemoteConnection.using(cluster));
// Configure retries
RetryConfig retryConfig = new RetryConfigBuilder()
.retryOnCustomExceptionLogic(getRetryLogic())
.withDelayBetweenTries(1000, ChronoUnit.MILLIS)
.withMaxNumberOfTries(5)
.withFixedBackoff()
.build();
@SuppressWarnings("unchecked")
CallExecutor<Object> retryExecutor = new CallExecutorBuilder<Object>()
.config(retryConfig)
.build();
// Do lots of queries
for (int i = 0; i < 100; i++){
String id = String.valueOf(i);
@SuppressWarnings("unchecked")
Callable<Object> query = () -> g.V(id)
.fold()
.coalesce(
unfold(),
addV("Person").property(T.id, id))
.id().next();
// Retry query
// If there are connection failures, the Java Gremlin client will automatically
// attempt to reconnect in the background, so all we have to do is wait and retry.
Status<Object> status = retryExecutor.execute(query);
System.out.println(status.getResult().toString());
}
cluster.close();
}
private static Function<Exception, Boolean> getRetryLogic() {
return e -> {
Class<? extends Exception> exceptionClass = e.getClass();
StringWriter stringWriter = new StringWriter();
String message = stringWriter.toString();
if (RemoteConnectionException.class.isAssignableFrom(exceptionClass)){
System.out.println("Retrying because RemoteConnectionException");
return true;
}
// Check for connection issues
if (message.contains("Timed out while waiting for an available host") ||
message.contains("Timed-out") && message.contains("waiting for connection on Host") ||
message.contains("Connection to server is no longer active") ||
message.contains("Connection reset by peer") ||
message.contains("SSLEngine closed already") ||
message.contains("Pool is shutdown") ||
message.contains("ExtendedClosedChannelException") ||
message.contains("Broken pipe") ||
message.contains(System.getenv("neptuneEndpoint")))
{
System.out.println("Retrying because connection issue");
return true;
};
// Concurrent writes can sometimes trigger a ConcurrentModificationException.
// In these circumstances you may want to backoff and retry.
if (message.contains("ConcurrentModificationException")) {
System.out.println("Retrying because ConcurrentModificationException");
return true;
}
// If the primary fails over to a new instance, existing connections to the old primary will
// throw a ReadOnlyViolationException. You may want to back and retry.
if (message.contains("ReadOnlyViolationException")) {
System.out.println("Retrying because ReadOnlyViolationException");
return true;
}
System.out.println("Not a retriable error");
return false;
};
}