As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
O exemplo de Java a seguir demonstra como se conectar ao cliente do Gremlin com a lógica de reconexão para se recuperar de uma desconexão inesperada.
As seguintes dependências se aplicam:
<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>
Aqui está o exemplo de código:
Importante
O CallExecutor
do Retry4j pode não ser livre de threads. Considere fazer com que cada thread use sua própria CallExecutor
instância ou use uma biblioteca de novas tentativas diferente.
nota
O exemplo a seguir foi atualizado para incluir o uso de requestInterceptor (). Isso foi adicionado na TinkerPop versão 3.6.6. Antes da TinkerPop versão 3.6.6, o exemplo de código usava handshakeInterceptor (), que foi descontinuado com essa versão.
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;
};
}