Långvariga operationer i Azure SDKs för Java

Den här artikeln förklarar långvariga åtgärder i Azure SDKs för Java och visar hur du spårar förloppet och hämtar slutliga resultat med mindre manuell avsökningslogik.

Vissa åtgärder på Azure tar längre tid att slutföra. De här åtgärderna följer inte http-standardformatet för snabbbegäran och svarsflöde. Till exempel är kopiering av data från en käll-URL till en lagringsblob, eller träning av en modell för att identifiera formulär, åtgärder som kan ta några sekunder till flera minuter. Dessa åtgärder är tidskrävande åtgärder, ofta förkortade som LRO. En LRO kan ta sekunder, minuter, timmar, dagar eller längre att slutföra, beroende på den begärda åtgärden och den process som servern måste utföra.

I Java klientbibliotek för Azure börjar alla långvariga åtgärder med prefixetbegin. Det här prefixet anger att åtgärden är tidskrävande och att interaktionssättet med den här åtgärden skiljer sig något från det vanliga flödet för begäran och svar. Tillsammans med prefixet begin är returtypen från åtgärden också annorlunda än vanligt, för att möjliggöra hela utbudet av funktionalitet för långvariga operationer. Precis som med de flesta saker i Azure SDKs för Java har långvariga åtgärder både synkrona och asynkrona API:er:

  • I synkrona klienter returnerar långvariga åtgärder en SyncPoller instans.
  • I asynkrona klienter returnerar långvariga åtgärder en PollerFlux instans.

Både SyncPoller och PollerFlux är abstraktioner på klientsidan som förenklar interaktionen med långvariga åtgärder på serversidan. Resten av den här artikeln beskriver metodtips när du arbetar med dessa typer.

Synkrona tidskrävande åtgärder

När du anropar ett API som returnerar en SyncPollerstartar den långvariga åtgärden direkt. API:t returnerar SyncPoller omedelbart, så att du kan övervaka förloppet för den tidskrävande åtgärden och få slutresultatet. I följande exempel visas hur du kan övervaka förloppet för en långvarig åtgärd med hjälp av 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());

I det här exemplet används poll()-metoden på SyncPoller för att hämta information om hur den långvariga åtgärden fortskrider. Den här koden skriver ut statusen till konsolen, men en bättre implementering fattar relevanta beslut baserat på den här statusen.

Metoden getRetryAfter() returnerar information om hur lång tid det tar att vänta före nästa omröstning. De flesta Azure-åtgärder som tar lång tid returnerar pollningsfördröjningen som en del av sitt HTTP-svar, det vill säga den vanliga retry-after headern. Om svaret inte innehåller pollningsfördröjningen returnerar metoden getRetryAfter() den varaktighet som angavs när den långvariga åtgärden anropades.

I föregående exempel används en do..while loop för att upprepade gånger avsöka tills den långvariga åtgärden har slutförts. Om du inte är intresserad av dessa mellanliggande resultat kan du i stället anropa waitForCompletion(). Det här anropet blockerar den aktuella tråden tills den långvariga åtgärden har slutförts och returnerar det senaste svaret från avsökningen:

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

Om svaret från den senaste avsökningen anger att den långvariga operationen har slutförts, kan du få det slutliga resultatet med hjälp av getFinalResult():

if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
    UploadedBlobProperties result = poller.getFinalResult();
}

Andra användbara API:er i SyncPoller är:

  • waitForCompletion(Duration): vänta tills den långvariga operationen slutförs inom den angivna timeoutperioden.
  • waitUntil(LongRunningOperationStatus): vänta tills den angivna långvariga åtgärdsstatusen har tagits emot.
  • waitUntil(LongRunningOperationStatus, Duration): vänta tills status för den långvariga åtgärden har tagits emot eller tills den angivna tidsgränsen går ut.

Asynkrona långvariga operationer

Följande exempel visar hur PollerFlux gör att du kan övervaka en långvarig operation. I asynkrona API:er sker nätverksanrop i en annan tråd än huvudtråden som anropar subscribe(). Den här arkitekturen innebär att huvudtråden kan avslutas innan resultatet är tillgängligt. Du måste se till att programmet inte avslutas innan asynkroniseringsåtgärden är klar.

Det asynkrona API:et returnerar en PollerFlux omedelbart, men den långvariga åtgärden i sig startar inte förrän du prenumererar på PollerFlux. Den här processen är hur alla Flux-baserade API:er fungerar. I följande exempel visas en asynkron tidskrävande åtgärd:

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

I följande exempel får du regelbundna statusuppdateringar om den långvariga processen. Du kan använda de här uppdateringarna för att avgöra om den långvariga åtgärden fortfarande fungerar på det förväntade sättet. Det här exemplet skriver ut statusen till konsolen, men en bättre implementering skulle göra relevanta felhanteringsbeslut baserat på den här statusen.

Om du inte är intresserad av mellanliggande statusuppdateringar och bara vill få ett meddelande om slutresultatet när det kommer använder du kod som liknar följande exempel:

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

I den här koden hämtar du slutresultatet av den långvariga åtgärden genom att anropa last(). Det här anropet talar om för PollerFlux att du vill vänta på att all polling ska slutföras. I det här läget når den långvariga åtgärden ett terminaltillstånd och du kan kontrollera dess status för att fastställa resultatet. Om polleraren anger att den långvariga åtgärden har slutförts kan du hämta det slutliga resultatet och skicka det vidare till konsumenten i prenumerationssamtalet.

Nästa steg

Nu när du är bekant med de långvariga API:erna i Azure SDKs för Java kan du läsa Konfigurera proxyservrar i Azure SDKs för Java för att lära dig hur du anpassar HTTP-klienten ytterligare.