Condividi tramite


Operazioni a esecuzione prolungata in Azure SDK per Java

Questo articolo offre una panoramica dell'uso di operazioni a esecuzione prolungata con Azure SDK per Java.

Il completamento di determinate operazioni in Azure può richiedere molto tempo. Queste operazioni non rientrano nello stile HTTP standard del flusso di richiesta/risposta rapida. Ad esempio, la copia di dati da un URL di origine a un BLOB Archiviazione o il training di un modello per riconoscere i moduli sono operazioni che possono richiedere alcuni secondi a diversi minuti. Tali operazioni vengono definite operazioni a esecuzione prolungata e spesso sono abbreviate come "LRO". Il completamento di un LRO può richiedere secondi, minuti, ore, giorni o più, a seconda dell'operazione richiesta e del processo che deve essere eseguito sul lato server.

Nelle librerie client Java per Azure esiste una convenzione che tutte le operazioni a esecuzione prolungata iniziano con il begin prefisso . Questo prefisso indica che questa operazione è a esecuzione prolungata e che il mezzo di interazione con questa operazione è leggermente diverso dal normale flusso di richiesta/risposta. Insieme al begin prefisso, anche il tipo restituito dell'operazione è diverso dal solito, per abilitare l'intero intervallo di funzionalità dell'operazione a esecuzione prolungata. Come per la maggior parte degli elementi in Azure SDK per Java, esistono sia API sincrone che asincrone per le operazioni a esecuzione prolungata:

  • Nei client sincroni, le operazioni a esecuzione prolungata restituiranno un'istanza SyncPoller di .
  • Nei client asincroni, le operazioni a esecuzione prolungata restituiranno un'istanza PollerFlux di .

Sia SyncPoller che PollerFlux sono astrazioni lato client destinate a semplificare l'interazione con operazioni lato server a esecuzione prolungata. Nella parte restante di questo articolo vengono descritte le procedure consigliate per l'uso di questi tipi.

Operazioni sincrone a esecuzione prolungata

La chiamata a qualsiasi API che restituisce un SyncPoller oggetto avvierà immediatamente l'operazione a esecuzione prolungata. L'API SyncPoller restituirà immediatamente, consentendo di monitorare lo stato di avanzamento dell'operazione a esecuzione prolungata e di recuperare il risultato finale. Nell'esempio seguente viene illustrato come monitorare lo stato di avanzamento di un'operazione a esecuzione prolungata usando .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());

In questo esempio viene utilizzato il poll() metodo su SyncPoller per recuperare informazioni sullo stato di avanzamento dell'operazione a esecuzione prolungata. Questo codice stampa lo stato nella console, ma un'implementazione migliore potrebbe prendere decisioni rilevanti in base a questo stato.

Il getRetryAfter() metodo restituisce informazioni sulla durata dell'attesa prima del polling successivo. La maggior parte delle operazioni a esecuzione prolungata di Azure restituisce il ritardo del polling come parte della risposta HTTP, ovvero l'intestazione comunemente usata retry-after . Se la risposta non contiene il ritardo del polling, il getRetryAfter() metodo restituisce la durata specificata al momento della chiamata dell'operazione a esecuzione prolungata.

Nell'esempio precedente viene usato un do..while ciclo per eseguire ripetutamente il polling fino al completamento dell'operazione a esecuzione prolungata. Se non si è interessati a questi risultati intermedi, è invece possibile chiamare waitForCompletion(). Questa chiamata blocca il thread corrente fino al completamento dell'operazione a esecuzione prolungata e restituisce l'ultima risposta di polling:

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

Se l'ultima risposta di polling indica che l'operazione a esecuzione prolungata è stata completata correttamente, è possibile recuperare il risultato finale usando getFinalResult():

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

Altre API utili in SyncPoller includono:

  1. waitForCompletion(Duration): attendere il completamento dell'operazione a esecuzione prolungata, per la durata del timeout specificata.
  2. waitUntil(LongRunningOperationStatus): attendere che venga ricevuto lo stato dell'operazione a esecuzione prolungata specificata.
  3. waitUntil(LongRunningOperationStatus, Duration): attendere fino alla ricezione dello stato dell'operazione a esecuzione prolungata specificata o fino alla scadenza della durata del timeout specificata.

Operazioni asincrone a esecuzione prolungata

L'esempio seguente illustra come l'oggetto PollerFlux consente di osservare un'operazione a esecuzione prolungata. Nelle API asincrone, le chiamate di rete vengono eseguite in un thread diverso rispetto al thread principale che chiama subscribe(). Ciò significa che il thread principale può terminare prima che il risultato sia disponibile. È necessario assicurarsi che l'applicazione non venga chiusa prima del completamento dell'operazione asincrona.

L'API asincrona restituisce immediatamente , PollerFlux ma l'operazione a esecuzione prolungata non verrà avviata fino a quando non si sottoscrive l'oggetto PollerFlux. Questo processo è il funzionamento di tutte le FluxAPI basate su . L'esempio seguente mostra un'operazione asincrona a esecuzione prolungata:

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

Nell'esempio seguente si otterranno aggiornamenti intermittenti dello stato per l'operazione a esecuzione prolungata. È possibile usare questi aggiornamenti per determinare se l'operazione a esecuzione prolungata è ancora operativa nel modo previsto. In questo esempio lo stato viene stampato nella console, ma un'implementazione migliore potrebbe prendere decisioni rilevanti per la gestione degli errori in base a questo stato.

Se non si è interessati agli aggiornamenti dello stato intermedio e si vuole ricevere una notifica del risultato finale al momento dell'arrivo, è possibile usare codice simile all'esempio seguente:

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

In questo codice si recupera il risultato finale dell'operazione a esecuzione prolungata chiamando last(). Questa chiamata indica PollerFlux che si vuole attendere il completamento di tutto il polling, a quel punto che l'operazione a esecuzione prolungata ha raggiunto uno stato terminale ed è possibile controllarne lo stato per determinare il risultato. Se il poller indica che l'operazione a esecuzione prolungata è stata completata correttamente, è possibile recuperare il risultato finale e passarlo al consumer nella chiamata di sottoscrizione.

Passaggi successivi

Ora che si ha familiarità con le API a esecuzione prolungata in Azure SDK per Java, vedere Configurare proxy in Azure SDK per Java per informazioni su come personalizzare ulteriormente il client HTTP.