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:
waitForCompletion(Duration)
: attendere il completamento dell'operazione a esecuzione prolungata, per la durata del timeout specificata.waitUntil(LongRunningOperationStatus)
: attendere che venga ricevuto lo stato dell'operazione a esecuzione prolungata specificata.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 Flux
API 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.