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),
]);

问题是 lambda 可能需要一分钟才能完成,这对于 PHP 到 return 对浏览器的响应来说是相当长的时间。

我想要异步调用函数,并在 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 状态,它就知道文件已准备好下载。