As APIsGoogle Cloud usam operações de longa duração (LROs) para chamadas que devem levar um tempo significativo para serem concluídas (por exemplo, provisionar uma instância do Compute Engine ou inicializar um pipeline do Dataflow).
Essas APIs não mantêm uma conexão ativa de longa duração nem bloqueiam enquanto a tarefa
é executada. Para APIs LRO, as bibliotecas de cliente do Cloud para Java retornam um future para você
verificar mais tarde.
Como determinar se uma API é uma LRO
Há duas maneiras principais de determinar se uma API é uma LRO:
- As APIs LRO têm o sufixo
Async(por exemplo,createClusterAsync) ouOperationCallable(por exemplo,createClusterOperationCallable). - As APIs LRO retornam um
OperationFutureou umOperationCallable.
O snippet a seguir mostra as duas variações, usando Java-Dataproc como um
exemplo:
// Async suffix (#1) returns OperationFuture (#2)
public final OperationFuture<Cluster, ClusterOperationMetadata> createClusterAsync(CreateClusterRequest request)
// OperationCallable suffix (#1) returns OperationCallable (#2)
public final OperationCallable<CreateClusterRequest, Cluster, ClusterOperationMetadata> createClusterOperationCallable()
São duas variações da mesma API, não duas APIs diferentes. As duas chamadas criam um cluster do Dataproc. A variante Async é recomendada.
Fluxo de alto nível de uma LRO
As APIs LRO são essencialmente uma chamada de solicitação inicial seguida por uma série de pequenas chamadas de sondagem. A chamada inicial envia a solicitação e cria uma "operação" no servidor. Todas as chamadas de pesquisa subsequentes para o servidor rastreiam o status da operação. Se a operação for concluída, a resposta será retornada. Caso contrário, um status incompleto será retornado, e a biblioteca de cliente vai determinar se é necessário fazer uma nova pesquisa.
Por padrão, o cliente processa a lógica de polling, e você não precisa configurar o mecanismo de polling, a menos que tenha requisitos específicos.
Do seu ponto de vista, a chamada é executada em segundo plano até que uma resposta seja recebida. As chamadas de pesquisa e as configurações de tempo limite têm valores padrão pré-configurados pela equipe de serviço com base no tempo esperado das APIs. Essas configurações controlam muitos fatores, como a frequência de sondagem e o tempo de espera antes de desistir.
As bibliotecas de cliente do Google Cloud para Java fornecem uma interface para interagir com a LRO usando OperationFuture.
O snippet a seguir mostra como chamar uma operação e aguardar uma resposta,
usando Java-Dataproc como exemplo:
try (ClusterControllerClient clusterControllerClient = ClusterControllerClient.create()) {
CreateClusterRequest request =
CreateClusterRequest.newBuilder().build();
OperationFuture<Cluster, ClusterOperationMetadata> future =
clusterControllerClient.createClusterAsync(request);
// Blocks until there is a response
Cluster response = future.get();
} catch (CancellationException e) {
// Exceeded the timeout without the Operation completing.
// Library is no longer polling for the Operation's status.
}
Valores padrão de LRO
Você pode encontrar os valores padrão na classe StubSettings de cada cliente. O método
initDefaults() inicializa as configurações de LRO na classe
Builder aninhada.
Por exemplo, em Java-Aiplatform v3.24.0, a chamada de LRO deployModel tem os seguintes parâmetros padrão:
OperationTimedPollAlgorithm.create(
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(5000L))
.setRetryDelayMultiplier(1.5)
.setMaxRetryDelayDuration(Duration.ofMillis(45000L))
.setTotalTimeoutDuration(Duration.ofMillis(300000L))
.setInitialRpcTimeoutDuration(Duration.ZERO) // not used
.setRpcTimeoutMultiplier(1.0) // not used
.setMaxRpcTimeoutDuration(Duration.ZERO) // not used
.build()));
As novas tentativas e as LROs compartilham a mesma classe RetrySettings. A tabela a seguir mostra o mapeamento entre os campos em RetrySettings e a funcionalidade de LRO:
| RetrySettings | Descrição |
|---|---|
| InitialRetryDelay | Atraso inicial antes da primeira pesquisa. |
| MaxRetryDelay | Atraso máximo entre cada pesquisa. |
| RetryDelayMultiplier | Multiplicador para o atraso entre novas tentativas de pesquisa. |
| TotalTimeoutDuration | Tempo máximo permitido para a operação de longa duração. |
Quando configurar valores de LRO
O principal caso de uso para configurar manualmente os valores de LRO é modificar as frequências de sondagem devido a tempos limite de LRO. Embora os valores padrão sejam configurados como uma estimativa pela equipe de serviço, alguns fatores podem resultar em tempos limite ocasionais.
Para reduzir o número de tempos limite, aumente o valor total do tempo limite. Aumentar os outros valores também pode ajudar. Teste-os para garantir o comportamento esperado.
Como configurar valores de LRO
Para configurar os valores de LRO, crie um objeto OperationTimedPollAlgorithm e atualize o algoritmo de pesquisa de uma LRO específica. O snippet a seguir usa
Java-Dataproc como exemplo:
ClusterControllerSettings.Builder settingsBuilder = ClusterControllerSettings.newBuilder();
// Create a new OperationTimedPollAlgorithm object
TimedRetryAlgorithm timedRetryAlgorithm = OperationTimedPollAlgorithm.create(
RetrySettings.newBuilder()
.setInitialRetryDelayDuration(Duration.ofMillis(500L))
.setRetryDelayMultiplier(1.5)
.setMaxRetryDelayDuration(Duration.ofMillis(5000L))
.setTotalTimeoutDuration(Duration.ofHours(24L))
.build());
// Set the new polling settings for the specific LRO API
settingsBuilder.createClusterOperationSettings().setPollingAlgorithm(timedRetryAlgorithm);
ClusterControllerClient clusterControllerClient = ClusterControllerClient.create(settingsBuilder.build());
Essa configuração modifica apenas os valores de LRO para a RPC createClusterOperation. As outras RPCs no cliente ainda usam os valores de LRO pré-configurados para cada RPC, a menos que também sejam modificados.
Tempos limite de LRO
A biblioteca continua fazendo pesquisas até que o tempo limite total seja excedido. Se o tempo limite total for excedido, a biblioteca vai gerar uma
java.util.concurrent.CancellationException com a mensagem "A tarefa foi
cancelada".
Um CancellationException não significa que a tarefa de back-end Google Cloud
foi cancelada. Essa exceção é gerada pela biblioteca de cliente quando uma
chamada excede o tempo limite total e não recebe uma resposta. Mesmo que a tarefa seja concluída imediatamente após o tempo limite, a biblioteca de cliente não vai receber a resposta.