適用於 Java 的 Azure SDK 中長時間執行的作業

本文提供搭配 Azure SDK for Java 使用長時間執行作業的概觀。

Azure 上的某些作業可能需要較長的時間才能完成。 這些作業超出快速要求/回應流程的標準 HTTP 樣式。 例如,將數據從來源 URL 複製到 儲存體 Blob,或將模型定型以辨識表單,是可能需要幾秒鐘到數分鐘的作業。 這類作業稱為「長時間執行的作業」,通常縮寫為 「LRO」。 LRO 可能需要幾秒鐘、分鐘、小時、天或更長的時間才能完成,視要求的作業和必須在伺服器端執行的程式而定。

在適用於 Azure 的 Java 用戶端連結庫中,存在所有長時間執行的作業開頭 begin 為前置詞的慣例。 此前置詞表示此作業長時間執行,而且與這項作業的互動方式與一般要求/回應流程稍有不同。 除了 begin 前置詞之外,作業的傳回型別也不同於平常,以啟用完整範圍的長時間執行作業功能。 如同適用於 Java 的 Azure SDK 中大部分項目一樣,長時間執行的作業都有同步和異步 API:

  • 在同步用戶端中,長時間執行的作業會傳 SyncPoller 回 實例。
  • 在異步用戶端中,長時間執行的作業會傳 PollerFlux 回 實例。

SyncPollerPollerFlux 都是用戶端抽象概念,旨在簡化與長時間執行伺服器端作業的互動。 本文的其餘部分會概述使用這些類型的最佳做法。

同步長時間執行的作業

呼叫任何傳 SyncPoller 回的 API 會立即啟動長時間執行的作業。 API 會立即傳回 SyncPoller ,讓您監視長時間執行的作業進度,並擷取最終結果。 下列範例示範如何使用 監視長時間執行作業 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());

這個範例使用 poll() 上的 SyncPoller 方法來擷取長時間執行作業進度的相關信息。 此程式代碼會將狀態列印至控制台,但更好的實作會根據此狀態做出相關決策。

方法 getRetryAfter() 會傳回下一次輪詢之前等待多久的資訊。 大部分的 Azure 長時間執行的作業都會傳迴輪詢延遲作為 HTTP 回應的一部分(也就是常用的 retry-after 標頭)。 如果回應未包含輪詢延遲,則 getRetryAfter() 方法會在叫用長時間執行的作業時傳回指定的持續時間。

上述範例會 do..while 使用迴圈重複輪詢,直到長時間執行的作業完成為止。 如果您對這些中繼結果不感興趣,您可以改為呼叫 waitForCompletion()。 此呼叫會封鎖目前的線程,直到長時間執行的作業完成並傳回最後一個輪詢回應:

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

如果最後一個輪詢回應指出長時間執行的作業已順利完成,您可以使用 擷取最終結果 getFinalResult()

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

中的其他 SyncPoller 實用 API 包括:

  1. waitForCompletion(Duration):等候長時間執行的作業完成,以取得指定的逾時持續時間。
  2. waitUntil(LongRunningOperationStatus):等候指定的長時間執行作業狀態收到。
  3. waitUntil(LongRunningOperationStatus, Duration):等到收到指定的長時間執行作業狀態,或等到指定的逾時持續時間到期為止。

異步長時間執行的作業

下列範例示範 如何 PollerFlux 讓您觀察長時間執行的作業。 在異步 API 中,網路呼叫發生在與呼叫 subscribe()的主要線程不同的線程中。 這表示主線程可能會在結果可用之前終止。 您必須確定應用程式在異步操作有時間完成之前不會結束。

異步 API 會立即傳 PollerFlux 回 ,但在您訂閱 PollerFlux之前,長時間執行的作業本身將不會啟動。 此程式是所有 Flux型 API 的運作方式。 下列範例顯示異步長時間執行的作業:

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

在下列範例中,您會在長時間執行的作業上取得間歇性狀態更新。 您可以使用這些更新來判斷長時間執行的作業是否仍以預期的方式運作。 此範例會將狀態列印至控制台,但較佳的實作會根據此狀態做出相關的錯誤處理決策。

如果您對中繼狀態更新不感興趣,而且只想在最終結果送達時收到通知,您可以使用類似下列範例的程式代碼:

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

在此程式代碼中,您會呼叫 last()來擷取長時間執行作業的最終結果。 此呼叫會告知 PollerFlux 您想要等候所有輪詢完成,此時長時間執行的作業已達到終端機狀態,您可以檢查其狀態以判斷結果。 如果輪詢器指出長時間執行的作業已順利完成,您可以擷取最終結果,並將它傳遞給訂閱呼叫中的取用者。

下一步

現在您已熟悉適用於 Java 的 Azure SDK 中長時間執行的 API,請參閱 在適用於 Java 的 Azure SDK 中設定 Proxy,以瞭解如何進一步自定義 HTTP 用戶端。