Amazon SDK for PHP 版本 3 中的 Waiter - Amazon SDK for PHP
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon SDK for PHP 版本 3 中的 Waiter

Waiter 通过对资源进行轮询,以一种抽象方式等待资源进入特定状态,从而更加轻松地使用最终一致性系统。您可以查看单一服务客户端版本的 API 文档,找到客户端支持的 Waiter 列表。要导航到那里,请转到 API 文档中的客户端页面,导航到特定版本号(用日期表示),然后向下滚动到“Waiter”部分。此链接将带您进入 S3 的“Waiter”部分。

在以下示例中,使用 Amazon S3 客户端来创建存储桶。然后使用 Waiter 等待存储桶建好。

// Create a bucket $s3Client->createBucket(['Bucket' => 'my-bucket']); // Wait until the created bucket is available $s3Client->waitUntil('BucketExists', ['Bucket' => 'my-bucket']);

如果 Waiter 轮询存储桶次数过多,会引发 \RuntimeException 异常。

Waiter 配置

Waiter 是由配置选项的关联数组推动的。特定 Waiter 所用的所有选项均有默认值,但可以覆盖这些默认值,以支持不同的等待策略。

@waiter 选项的关联数组传递到客户端的 waitUntil()getWaiter() 方法的 $args 参数,可以修改 Waiter 配置选项。

// Providing custom waiter configuration options to a waiter $s3Client->waitUntil('BucketExists', [ 'Bucket' => 'my-bucket', '@waiter' => [ 'delay' => 3, 'maxAttempts' => 10 ] ]);
delay (int)

两次轮询尝试之间的延迟秒数。每个 Waiter 都有默认的 delay 配置值,但您可能需要针对具体的使用情形修改此设置。

maxAttempts (int)

Waiter 失败之前轮询尝试的次数上限。此选项可确保您不会无限期地等待某个资源。每个 Waiter 都有默认的 maxAttempts 配置值,但您可能需要针对具体的使用情形修改此设置。

initDelay (int)

首次轮询尝试之前等待的秒数。如果您知道某一资源需要一段时间才能进入所需状态,此选项将会很有用。

before(可调用)

一个 PHP 可调用函数,在每次尝试之前调用。该可调用函数根据将要执行的 Aws\CommandInterface 命令以及目前已执行的尝试次数调用。before 可调用函数的用途可以是在执行命令之前修改命令,或提供进度信息。

use Aws\CommandInterface; $s3Client->waitUntil('BucketExists', [ 'Bucket' => 'my-bucket', '@waiter' => [ 'before' => function (CommandInterface $command, $attempts) { printf( "About to send %s. Attempt %d\n", $command->getName(), $attempts ); } ] ]);

异步等待

除了同步等待,您还可以调用 Waiter 异步等待,同时发送其他请求或同时等待多个资源。

您可以使用客户端的 getWaiter($name, array $args = []) 方法检索客户端的 Waiter,从而访问 Waiter 的 Promise。使用 Waiter 的 promise() 方法启动 Waiter。Waiter 中最近执行的 Aws\CommandInterface 可满足 Waiter Promise,错误引起的 RuntimeException 可拒绝 Waiter Promise。

use Aws\CommandInterface; $waiterName = 'BucketExists'; $waiterOptions = ['Bucket' => 'my-bucket']; // Create a waiter promise $waiter = $s3Client->getWaiter($waiterName, $waiterOptions); // Initiate the waiter and retrieve a promise $promise = $waiter->promise(); // Call methods when the promise is resolved. $promise ->then(function () { echo "Waiter completed\n"; }) ->otherwise(function (\Exception $e) { echo "Waiter failed: " . $e . "\n"; }); // Block until the waiter completes or fails. Note that this might throw // a \RuntimeException if the waiter fails. $promise->wait();

公开基于 Promise 的 Waiter API 适用于一些功能强大、开销相对较低的使用情形。例如,如果您希望等待多个资源,并在第一个 Waiter 成功完成后执行某些操作,这时该怎么办呢?

use Aws\CommandInterface; // Create an array of waiter promises $promises = [ $s3Client->getWaiter('BucketExists', ['Bucket' => 'a'])->promise(), $s3Client->getWaiter('BucketExists', ['Bucket' => 'b'])->promise(), $s3Client->getWaiter('BucketExists', ['Bucket' => 'c'])->promise() ]; // Initiate a race between the waiters, fulfilling the promise with the // first waiter to complete (or the first bucket to become available) $any = Promise\any($promises) ->then(function (CommandInterface $command) { // This is invoked with the command that succeeded in polling the // resource. Here we can know which bucket won the race. echo "The {$command['Bucket']} waiter completed first!\n"; }); // Force the promise to complete $any->wait();