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 di 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 Long-Running 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 prefisso begin, anche il tipo di ritorno dell'operazione è diverso dal solito, per abilitare tutta la gamma 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.
  • Nei client asincroni, le operazioni a esecuzione prolungata restituiranno un'istanza di PollerFlux.

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 di lunga durata

La chiamata a qualsiasi API che restituisce un SyncPoller avvierà immediatamente l'operazione a lungo termine. L'API restituirà immediatamente il SyncPoller, permettendoti di monitorare lo stato di avanzamento dell'operazione a lungo termine 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, il metodo poll() viene utilizzato su SyncPoller per recuperare informazioni sullo stato di avanzamento di un'operazione 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 di polling, il metodo getRetryAfter() restituisce la durata specificata al momento di invocare l'operazione a esecuzione prolungata.

Nell'esempio precedente viene usato un do..while ciclo per effettuare ripetutamente il polling fino al completamento dell'operazione di lunga durata. Se non si è interessati a questi risultati intermedi, è invece possibile chiamare waitForCompletion(). La presente chiamata blocca il thread corrente fino al completamento dell'operazione prolungata e restituisce la risposta dell'ultimo sondaggio.

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

Se la risposta all'ultimo sondaggio indica che l'operazione a esecuzione prolungata è stata completata correttamente, puoi 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 si riceva lo stato dell'operazione in corso 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 lungo termine

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. Spetta a te assicurarti che l'applicazione non si chiuda 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. Il modo in cui funzionano tutte le API basate su Flux è attraverso questo processo. 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 di lunga durata. È 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 desidera attendere il completamento di tutto il polling, a quel punto l'operazione di lunga durata ha raggiunto uno stato terminale ed è possibile ispezionare 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 consumatore nella chiamata di sottoscrizione.

Passaggi successivi

Ora che si ha familiarità con le API a esecuzione prolungata nel Azure SDK per Java, consultare Configurare i proxy nell'Azure SDK per Java per scoprire come personalizzare ulteriormente il client HTTP.