Operações de longa execução no SDK do Azure para Java

Este artigo fornece uma visão geral do uso de operações de longa execução com o SDK do Azure para Java.

Determinadas operações no Azure podem levar muito tempo para serem concluídas. Essas operações estão fora do estilo HTTP padrão de fluxo rápido de solicitação/resposta. 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 referidas como operações de longa duração e são frequentemente abreviadas como «LRO». Um LRO pode levar segundos, minutos, horas, dias ou mais para ser concluído, dependendo da operação solicitada e do processo que deve ser executado no lado do servidor.

Nas bibliotecas de cliente Java para Azure, existe uma convenção de que todas as operações de longa execução começam com o prefixo begin . Este prefixo indica que esta operação é de longa duração, e que o meio de interação com esta operação é ligeiramente diferente do fluxo habitual de solicitação/resposta. Junto com o prefixo, o begin tipo de retorno da operação também é diferente do habitual, para permitir a gama completa de funcionalidade de operação de longa duração. 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, operações de longa execução retornarão uma SyncPoller instância.
  • Em clientes assíncronos, operações de longa execução retornarão uma PollerFlux instância.

Ambos SyncPoller e PollerFlux são as abstrações do lado do cliente destinadas a simplificar a interação com operações de longa execução do lado do servidor. O restante deste artigo descreve as práticas recomendadas ao trabalhar com esses tipos.

Operações síncronas de longa duração

Chamar qualquer API que retorne um SyncPoller iniciará imediatamente a operação de longa execução. A API retornará o imediatamente, permitindo que você monitore o progresso da operação de longa duração e recupere o SyncPoller resultado final. O exemplo a seguir mostra como monitorar o progresso de uma operação de longa execução 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 poll() método no para recuperar informações sobre o SyncPoller progresso da operação de longa duração. Esse código imprime o status no console, mas uma implementação melhor tomaria decisões relevantes com base nesse status.

O getRetryAfter() método retorna informações sobre quanto tempo esperar antes da próxima pesquisa. A maioria das operações de longa execução do Azure retorna o atraso da sondagem como parte de sua resposta HTTP (ou seja, o cabeçalho comumente usado retry-after ). Se a resposta não contiver o atraso da sondagem, o getRetryAfter() método retornará a duração dada no momento da invocação da operação de longa duração.

O exemplo acima usa um do..while loop para sondar repetidamente até que a operação de longa duração seja concluída. Se você não estiver interessado nesses resultados intermediários, você pode ligar waitForCompletion()para . Esta chamada bloqueará o thread atual até que a operação de longa duração seja concluída e retorne a última resposta da pesquisa:

PollResponse<UploadBlobProgress> response = poller.waitForCompletion();

Se a última resposta da sondagem indicar que a operação de longa duração 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 incluem SyncPoller :

  1. waitForCompletion(Duration): aguarde a conclusão da operação de longa duração, pela duração do tempo limite dado.
  2. waitUntil(LongRunningOperationStatus): aguarde até que o status da operação de longa duração seja recebido.
  3. waitUntil(LongRunningOperationStatus, Duration): aguarde até que o status da operação de longa duração seja recebido ou até que a duração do tempo limite determinado expire.

Operações assíncronas de longa duração

O exemplo abaixo mostra como o PollerFlux permite observar uma operação de longa duração. Em APIs assíncronas, as chamadas de rede acontecem em um thread diferente do thread principal que chama subscribe(). O que isso significa é que o thread principal pode terminar antes que o resultado esteja disponível. Cabe a você garantir que o aplicativo não saia antes que a operação assíncrona tenha tido tempo de ser concluída.

A API assíncrona retorna um PollerFlux imediatamente, mas a operação de longa execução em si não será iniciada até que você assine o PollerFlux. Esse processo é como todas as FluxAPIs baseadas operam. O exemplo a seguir mostra uma operação de longa execução assíncrona:

asyncClient.beginUploadFromUri(...)
    .subscribe(response -> System.out.println("Status of long running upload operation: " + response.getStatus()));

No exemplo a seguir, você receberá atualizações de status intermitentes na operação de longa duração. Você pode usar essas atualizações para determinar se a operação de longa duração ainda está operando da maneira esperada. Este exemplo imprime o status no console, mas uma implementação melhor tomaria decisões relevantes de tratamento de erros 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, você pode usar um código semelhante ao exemplo a seguir:

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());

Neste código, você recupera o resultado final da operação de longa execução chamando last(). Essa chamada informa que PollerFlux você deseja aguardar a conclusão de toda a sondagem, momento em que a operação de longa duração atingiu um estado terminal e você pode inspecionar seu status para determinar o resultado. Se o poller indicar que a operação de longa duração foi concluída com êxito, você pode recuperar o resultado final e passá-lo para o consumidor na chamada de assinatura.

Próximos passos

Agora que você está familiarizado com as APIs de longa execução no SDK do Azure para Java, consulte Configurar proxies no SDK do Azure para Java para saber como personalizar ainda mais o cliente HTTP.