Operações de execução longa no SDK do Azure para Java
Este artigo apresenta uma visão geral do uso de operações de execução longa com o SDK do Azure para Java.
Determinadas operações no Azure podem levar um tempo maior para serem concluídas. Essas operações estão fora do estilo HTTP padrão de fluxo de solicitação/resposta rápido. Por exemplo, copiar dados de uma URL de origem para um Blob de Armazenamento ou treinar um modelo para reconhecer formulários são operações que podem levar de alguns segundos a vários minutos. Essas operações são chamadas de operações de execução longa e geralmente são abreviadas como LRO. Uma LRO pode levar segundos, minutos, horas, dias ou mais para ser concluída, dependendo da operação solicitada e do processo que deve ser executado no lado do servidor.
Nas bibliotecas de clientes Java do Azure, existe uma convenção de que todas as operações de execução longa começam com o prefixo begin
. Esse prefixo indica que essa operação é de execução longa e que o modo de interação com ela é um pouco diferente do fluxo de solicitação/resposta usual. Junto com o prefixo begin
, o tipo retornado da operação também é diferente do usual para habilitar toda a gama de funcionalidades da operação de execução longa. Assim como acontece com a maioria das coisas no SDK do Azure para Java, há APIs síncronas e assíncronas para operações de longa execução:
- Em clientes síncronos, as operações de execução longa retornarão uma instância de
SyncPoller
. - Em clientes assíncronos, as operações de execução longa retornarão uma instância de
PollerFlux
.
Tanto SyncPoller
quanto PollerFlux
são as abstrações do lado do cliente destinadas a simplificar a interação com operações de longa duração do servidor. O restante deste artigo descreve as práticas recomendadas ao trabalhar com esses tipos.
Operações de longa execução síncronas
Chamar qualquer API que retorna um SyncPoller
iniciará imediatamente a operação de execução longa. A API retornará o SyncPoller
imediatamente, permitindo que você monitore o progresso da operação de execução longa e recupere o resultado final. O exemplo a seguir mostra como monitorar o progresso de uma operação de execução longa usando o SyncPoller
.
SyncPoller<UploadBlobProgress, UploadedBlobProperties> poller = syncClient.beginUploadFromUri(<URI to upload from>)
PollResponse<UploadBlobProgress> response;
do {
response = poller.poll();
System.out.println("Status of long running upload operation: " + response.getStatus());
Duration pollInterval = response.getRetryAfter();
TimeUnit.MILLISECONDS.sleep(pollInterval.toMillis());
} while (!response.getStatus().isComplete());
Este exemplo usa o método poll()
no SyncPoller
para recuperar informações sobre o progresso da operação de execução longa. Esse código imprime o status no console, porém, uma implementação melhor tomaria decisões relevantes com base nesse status.
O método getRetryAfter()
retorna informações sobre o tempo de espera antes da próxima sondagem. A maioria das operações de execução longa do Azure retorna o atraso de sondagem como parte da resposta HTTP (ou seja, o cabeçalho retry-after
comumente usado). Se a resposta não contiver o atraso de sondagem, o método getRetryAfter()
retornará a duração fornecida no momento da invocação da operação de execução longa.
O exemplo acima usa um loop do..while
para sondar repetidamente até que a operação de execução longa seja concluída. Se você não estiver interessado nesses resultados intermediários, poderá chamar waitForCompletion()
. Essa chamada bloqueará o thread atual até que a operação de execução longa seja concluída e retorne a última resposta de sondagem:
PollResponse<UploadBlobProgress> response = poller.waitForCompletion();
Se a última resposta de sondagem indicar que a operação de execução longa foi concluída com êxito, você poderá recuperar o resultado final usando getFinalResult()
:
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
UploadedBlobProperties result = poller.getFinalResult();
}
Outras APIs úteis no SyncPoller
incluem:
waitForCompletion(Duration)
: aguardar a conclusão da operação de execução longa pela duração do tempo limite especificada.waitUntil(LongRunningOperationStatus)
: aguardar até que o status da operação de execução longa seja recebido.waitUntil(LongRunningOperationStatus, Duration)
: aguardar até que o status da operação de execução longa seja recebido ou a duração do tempo limite determinada expire.
Operações de execução longa assíncronas
O exemplo a seguir mostra como o PollerFlux
permite que você observe uma operação de execução longa. Em APIs assíncronas, as chamadas de rede acontecem em um thread diferente do thread principal que chama subscribe()
. Isso significa que o thread principal pode terminar antes que o resultado esteja disponível. Cabe a você garantir que o aplicativo não seja encerrado antes que a operação assíncrona tenha tido tempo para ser concluída.
A API assíncrona retorna um PollerFlux
imediatamente, mas a operação de execução longa em si não será iniciada até que você assine o PollerFlux
. Esse processo é como todas as APIs baseadas em Flux
operam. O seguinte exemplo mostra uma operação de execução longa assíncrona:
asyncClient.beginUploadFromUri(...)
.subscribe(response -> System.out.println("Status of long running upload operation: " + response.getStatus()));
No exemplo a seguir, você obterá atualizações de status intermitentes na operação de execução longa. Você pode usar essas atualizações para determinar se a operação de execução longa ainda está operando no modo esperado. Esse exemplo imprime o status no console, porém, uma implementação melhor tomaria decisões relevantes de tratamento de erro com base nesse status.
Se você não estiver interessado nas atualizações de status intermediárias e quiser apenas ser notificado do resultado final quando ele chegar, poderá usar um código semelhante ao seguinte exemplo:
asyncClient.beginUploadFromUri(...)
.last()
.flatMap(response -> {
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
return response.getFinalResult();
}
return Mono.error(new IllegalStateException("Polling completed unsuccessfully with status: "+ response.getStatus()));
})
.subscribe(
finalResult -> processFormPages(finalResult),
ex -> countDownLatch.countDown(),
() -> countDownLatch.countDown());
Nesse código, você recupera o resultado final da operação de execução longa chamando last()
. Essa chamada informa o PollerFlux
que você deseja aguardar até que toda a sondagem seja concluída; nesse ponto, a operação de execução longa atingiu um estado de terminal e você pode inspecionar seu status para determinar o resultado. Se o verificador indicar que a operação de execução longa foi concluída com êxito, você poderá recuperar o resultado final e passá-lo para o consumidor na chamada de assinatura.
Próximas etapas
Agora que você está familiarizado com as APIs de execução longa no SDK do Azure para Java, confira Configurar proxies no SDK do Azure para Java para aprender a personalizar ainda mais o cliente HTTP.