Azure SDK for Java 中的长期操作
本文概述如何在 Azure SDK for Java 中使用长期操作。
Azure 上的某些操作可能需要花费很长时间才能完成。 这些操作不是标准 HTTP 样式的快速请求/响应流。 例如,将数据从源 URL 复制到存储 blob 或训练模型来识别表单时,可能需要花费几秒钟到几分钟的时间。 此类操作称为长期操作,通常缩写为“LRO”。 LRO 可能需要几秒钟、几分钟、几小时、几天或更长时间才能完成,具体取决于所请求的操作和必须在服务器端执行的进程。
在 Azure 的 Java 客户端库中,存在一个约定,即所有长期操作都以 begin
前缀开头。 此前缀表示此操作长期运行,并且与此操作交互的方法与常规的请求/响应流略有不同。 除了 begin
前缀以外,此操作的返回类型也与常规的不同,目的是实现完整的长期操作功能。 与 Azure SDK for Java 中的大部分操作一样,长期操作有同步 API 和异步 API:
- 在同步客户端中,长期操作将返回一个
SyncPoller
实例。 - 在异步客户端中,长期操作将返回一个
PollerFlux
实例。
SyncPoller
和 PollerFlux
都是客户端抽象,旨在简化与长期服务器端操作的交互。 本文的其余部分概括介绍使用这些类型时的最佳做法。
调用任何返回 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());
此示例使用 SyncPoller
上的 poll()
方法来检索有关长期操作进度的信息。 此代码会将状态输出到控制台,但更好的实现方式会根据此状态做出相关决策。
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 包括:
waitForCompletion(Duration)
:等待长期操作完成,时限为给定的超时持续时间。waitUntil(LongRunningOperationStatus)
:等待,直到收到给定的长期操作状态。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
你需要等待所有轮询完成,此时长期操作已达到终端状态,你可检查其状态以确定结果。 如果轮询器指示长期操作已成功完成,你可检索最终结果,并将其传递给订阅调用中的使用者。
现在你已熟悉 Azure SDK for Java 中的长期 API,请参阅在 Azure SDK for Java 中配置代理,了解如何进一步自定义 HTTP 客户端。