AWS SDK (PHP):异步调用 lambda 函数,检索状态
AWS SDK (PHP): Invoking lambda function asynchronously, retrieving status
我们有一个 AWS lambda 函数,用于在 down 加载之前进行一些可怕的专有文件格式处理和自定义,这是通过 AWS SDK 从 PHP 触发的。 lambda 从 s3 存储桶中抓取文件,将一些元数据插入到文件中,对其进行压缩,并将其放在 s3 上的临时存储桶中,以便在客户结账时下载。
lambda 部分通过 invoke/invokeAsync:
完美运行
use Aws\Sdk;
...
$lambdaclient = $this->sdk->createClient('lambda',$region);
$syncresult = $lambdaclient->invoke([
'FunctionName' => $functionName,
'InvocationType' => 'RequestResponse',
'Payload' => json_encode($payload),
]);
$asyncresult = $lambdaclient->invoke([
'FunctionName' => $functionName,
'InvocationType' => 'Event',
'Payload' => json_encode($payload),
]);
$promise = $lambdaclient->invokeAsync([
'FunctionName' => $functionName,
'Payload' => json_encode($payload),
]);
- $syncresult 将包含 lambda 函数的 succeed/fail 状态,可选地带有日志(通过 LogType Tail)。
问题是 lambda 可能需要一分钟才能完成,这对于 PHP 到 return 对浏览器的响应来说是相当长的时间。
$asyncresult 将调用该函数,并且 return HTTP 状态 202,但以后无法检查该函数是否实际执行了任何操作。
$promise 是一个 Guzzle promise,它被 AWS SDK 广泛使用,可以在 PHP 中绑定一个函数到它,以便在 lambda 完成时执行.这似乎非常有用,只要 PHP 没有 return 对浏览器的响应,因为到那时你就失去了承诺。您可以调用 $result = $promise->wait()
让它解决。这些承诺的主要优势似乎是 运行 多个 lambda 并发,并将结果合并到一个 PHP 请求中。
我想要异步调用函数,并在 laterPHP 请求中检查函数状态(存储一些对调用的引用也许在会话数据中?)。这样,我可以稍后使用 Ajax 请求轮询状态,并确保当我为最终文件创建一个签名的 s3 URL 时,一切都没有错误地完成。
使用 AWS SDK 可以实现这样的事情吗?或者有更好的解决方案吗?
编辑:
我决定使用从客户端 ajax 调用中触发的 invokeAsync,该调用已中止(不等待应答)。 PHP 脚本有相当多的时间来完成(使用 settimelimit),因为对 lambda 的调用是 运行 并发的,浏览器不再等待了。
我将 promise 存储在数组中,并使用:
$values = array_map(function($result){
return json_decode($result->toArray()['Payload']->getContents());
}, Promise\unwrap($promises));
获取响应负载(它们被 AWS SDK 包装在流接口中),并将它们写入(在我的例子中,DynamoDB,SQL/session/cache 可能都可以)。
当最终用户需要结果时,我只是简单地检查存储的数据以及转换后的文件是否存在于s3上。
我可能会改进 ajax 处理,方法是尝试从 PHP 刷新输出缓冲区,使用一些 returned ID 正确完成调用,同时允许 PHP 等待AWS的承诺。
是的,你可以做到这一点,但我不确定你是否可以纯粹使用 Lambda 来做到这一点。我的处理方式是这样的:
1) 当您当前的 PHP 代码被命中时,添加使用 AWS SNS 发送一条消息,其中包含有关函数和参数的详细信息。立即 return 向浏览器发送一条消息,其中包含有关要在 s3 中监视的文件的信息。然后让您的浏览器轮询我在步骤 3 中描述的端点。
2) 设置您的 lambda 函数以侦听 SNS 消息并自动 运行 (http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html)
3) 有另一个 PHP 端点,您可以使用 AJAX 命中它来检查 lambda 创建的文件是否已创建完毕。如果没有 return 一条消息说它还没有准备好,一旦文件存在然后 return 一条消息说它已经准备好了。
如果您不想使用纯粹的 AWS 方法,那么您可以这样做:
1) 当您当前的 PHP 代码被命中时,向数据库 table 添加一条记录,其中包含有关需要 运行 的函数和参数的信息以及类似 queued
。立即将数据库中记录的 id
发送回浏览器。然后让您的浏览器轮询我在步骤 3 中描述的端点。
2) 设置一个单独的 php 脚本,该脚本 运行 连续运行或通过 cron 或其他方式触发,每隔几秒检查一次上面创建的 table 的条目queued
的状态。将记录状态更新为 processing
之类的内容,这样就不会意外地再次获得 运行。现在让它触发 Lambda 函数并使用承诺。完成后,将记录状态更新为 complete
.
3) 有另一个 PHP 端点,您可以使用 AJAX 将其传递给第一步中收到的 ID,并简单地 return 记录状态。一旦浏览器返回 complete
状态,它就知道文件已准备好下载。
我们有一个 AWS lambda 函数,用于在 down 加载之前进行一些可怕的专有文件格式处理和自定义,这是通过 AWS SDK 从 PHP 触发的。 lambda 从 s3 存储桶中抓取文件,将一些元数据插入到文件中,对其进行压缩,并将其放在 s3 上的临时存储桶中,以便在客户结账时下载。
lambda 部分通过 invoke/invokeAsync:
完美运行use Aws\Sdk;
...
$lambdaclient = $this->sdk->createClient('lambda',$region);
$syncresult = $lambdaclient->invoke([
'FunctionName' => $functionName,
'InvocationType' => 'RequestResponse',
'Payload' => json_encode($payload),
]);
$asyncresult = $lambdaclient->invoke([
'FunctionName' => $functionName,
'InvocationType' => 'Event',
'Payload' => json_encode($payload),
]);
$promise = $lambdaclient->invokeAsync([
'FunctionName' => $functionName,
'Payload' => json_encode($payload),
]);
- $syncresult 将包含 lambda 函数的 succeed/fail 状态,可选地带有日志(通过 LogType Tail)。
问题是 lambda 可能需要一分钟才能完成,这对于 PHP 到 return 对浏览器的响应来说是相当长的时间。
$asyncresult 将调用该函数,并且 return HTTP 状态 202,但以后无法检查该函数是否实际执行了任何操作。
$promise 是一个 Guzzle promise,它被 AWS SDK 广泛使用,可以在 PHP 中绑定一个函数到它,以便在 lambda 完成时执行.这似乎非常有用,只要 PHP 没有 return 对浏览器的响应,因为到那时你就失去了承诺。您可以调用
$result = $promise->wait()
让它解决。这些承诺的主要优势似乎是 运行 多个 lambda 并发,并将结果合并到一个 PHP 请求中。
我想要异步调用函数,并在 laterPHP 请求中检查函数状态(存储一些对调用的引用也许在会话数据中?)。这样,我可以稍后使用 Ajax 请求轮询状态,并确保当我为最终文件创建一个签名的 s3 URL 时,一切都没有错误地完成。
使用 AWS SDK 可以实现这样的事情吗?或者有更好的解决方案吗?
编辑:
我决定使用从客户端 ajax 调用中触发的 invokeAsync,该调用已中止(不等待应答)。 PHP 脚本有相当多的时间来完成(使用 settimelimit),因为对 lambda 的调用是 运行 并发的,浏览器不再等待了。
我将 promise 存储在数组中,并使用:
$values = array_map(function($result){
return json_decode($result->toArray()['Payload']->getContents());
}, Promise\unwrap($promises));
获取响应负载(它们被 AWS SDK 包装在流接口中),并将它们写入(在我的例子中,DynamoDB,SQL/session/cache 可能都可以)。
当最终用户需要结果时,我只是简单地检查存储的数据以及转换后的文件是否存在于s3上。
我可能会改进 ajax 处理,方法是尝试从 PHP 刷新输出缓冲区,使用一些 returned ID 正确完成调用,同时允许 PHP 等待AWS的承诺。
是的,你可以做到这一点,但我不确定你是否可以纯粹使用 Lambda 来做到这一点。我的处理方式是这样的:
1) 当您当前的 PHP 代码被命中时,添加使用 AWS SNS 发送一条消息,其中包含有关函数和参数的详细信息。立即 return 向浏览器发送一条消息,其中包含有关要在 s3 中监视的文件的信息。然后让您的浏览器轮询我在步骤 3 中描述的端点。
2) 设置您的 lambda 函数以侦听 SNS 消息并自动 运行 (http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html)
3) 有另一个 PHP 端点,您可以使用 AJAX 命中它来检查 lambda 创建的文件是否已创建完毕。如果没有 return 一条消息说它还没有准备好,一旦文件存在然后 return 一条消息说它已经准备好了。
如果您不想使用纯粹的 AWS 方法,那么您可以这样做:
1) 当您当前的 PHP 代码被命中时,向数据库 table 添加一条记录,其中包含有关需要 运行 的函数和参数的信息以及类似 queued
。立即将数据库中记录的 id
发送回浏览器。然后让您的浏览器轮询我在步骤 3 中描述的端点。
2) 设置一个单独的 php 脚本,该脚本 运行 连续运行或通过 cron 或其他方式触发,每隔几秒检查一次上面创建的 table 的条目queued
的状态。将记录状态更新为 processing
之类的内容,这样就不会意外地再次获得 运行。现在让它触发 Lambda 函数并使用承诺。完成后,将记录状态更新为 complete
.
3) 有另一个 PHP 端点,您可以使用 AJAX 将其传递给第一步中收到的 ID,并简单地 return 记录状态。一旦浏览器返回 complete
状态,它就知道文件已准备好下载。