node.js - lambda 触发器回调 vs context.done

标签 node.js amazon-web-services aws-lambda amazon-cognito amazon-cognito-triggers

我在跟着指南here用于设置预注册触发器。

但是,当我使用 callback(null, event) 时我的 lambda 函数永远不会真正返回,我最终会得到一个错误

{ code: 'UnexpectedLambdaException', name: 'UnexpectedLambdaException', message: 'arn:aws:lambda:us-east-2:642684845958:function:proj-dev-confirm-1OP5DB3KK5WTA failed with error Socket timeout while invoking Lambda function.' }



我发现了一个类似的 link here说要使用 context.done() .

切换后它工作得很好。

有什么不同?
exports.confirm = (event, context, callback) => {
    event.response.autoConfirmUser = true;
    context.done(null, event);
    //callback(null, event); does not work
}

最佳答案

回到 Node.js 0.10 的原始 Lambda 运行时环境,Lambda 在 context 中提供了辅助函数。对象:context.done(err, res) context.succeed(res)context.fail(err) .

这是以前记录的,但已被删除。

Using the Earlier Node.js Runtime v0.10.42是 Lambda 文档中不再存在的页面的存档副本,它解释了如何使用这些方法。

当用于 Lambda 的 Node.js 4.3 运行时启动时,这些仍然是为了向后兼容(并且仍然可用但未记录)和 callback(err, res)被介绍了。

这是您的问题的性质,以及为什么您找到的两个解决方案实际上似乎可以解决它。

Context.succeed, context.done, and context.fail however, are more than just bookkeeping – they cause the request to return after the current task completes and freeze the process immediately, even if other tasks remain in the Node.js event loop. Generally that’s not what you want if those tasks represent incomplete callbacks.

https://aws.amazon.com/blogs/compute/node-js-4-3-2-runtime-now-available-on-lambda/



所以与 callback ,Lambda 函数现在以更正确的方式运行,但是如果您希望某些对象在调用之间发生的卡住期间保留在事件循环中,这是一个问题——与旧的(已弃用)不同 done fail succeed方法,使用回调不会立即挂起事情。相反,它等待事件循环为空。

context.callbackWaitsForEmptyEventLoop -- 默认 true -- 被引入以便您可以将其设置为 false对于您希望 Lambda 函数在调用回调后立即返回的情况,无论事件循环中发生了什么。默认为 true因为 false可能会掩盖函数中的错误,如果您没有考虑容器重用的影响,可能会导致非常不稳定/意外的行为——因此您不应将其设置为 false除非并且直到您明白为什么需要它。

一个常见的原因 false需要的是由您的函数建立的数据库连接。如果你在一个全局变量中创建一个数据库连接对象,它将有一个打开的套接字,以及潜在的其他东西,比如计时器,坐在事件循环中。这可以防止回调导致 Lambda 返回响应,直到这些操作也完成或调用超时计时器触发。

确定为什么需要将其设置为 false ,如果这是一个正当的理由,那么使用它是正确的。

否则,在调用回调时,您的代码可能存在您需要了解和修复的错误,例如使请求处于飞行状态或其他未完成的工作。

那么,我们如何解析 Cognito 错误呢?起初,这似乎很不寻常,但现在很明显事实并非如此。

在执行函数时,Lambda 会在配置的秒数后抛出任务超时的错误。您应该会发现这是在 Lambda 控制台中测试您的函数时发生的情况。

不幸的是,Cognito 在调用 Lambda 函数时似乎采用了内部设计捷径,而不是等待 Lambda 使调用超时(这可能会占用 Cognito 内部的资源)或在 Cognito 将等待的最大持续时间上强加自己的显式计时器Lambda 响应,它依赖于下层套接字计时器来限制此等待……因此在调用超时时会引发“意外”错误。

错误消息的解释更加复杂,错误中缺少引号,其中插入了下层异常。

对我来说,如果错误如下所示,问题会更清楚:
'arn:aws:lambda:...' failed with error 'Socket timeout' while invoking Lambda function

这种格式会更清楚地表明,当 Cognito 调用该函数时,它抛出了一个内部 Socket timeout错误(而不是 Lambda 遇到意外的内部错误,这是我最初的——也是不正确的——假设)。

Cognito 对 Lambda 函数施加某种响应时间限制是非常合理的,但我没有看到这一点。我怀疑您的 Lambda 函数本身的短暂超时(使其更迅速地失败)会导致 Cognito 抛出一个更有用的错误,但在我看来,Cognito 应该被设计为包含逻辑以使其成为预期的、定义的错误,而不是将其归类为“意外”。

关于node.js - lambda 触发器回调 vs context.done,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54846513/

相关文章:

node.js - Nodejs异步: concurency worker push the same task again in the queue

amazon-web-services - Cloudformation : access other resources in the stack folder, 文件夹在哪里?

amazon-web-services - Cloudfront s3 分发中的有序缓存导致访问被拒绝 (403)

javascript - 如何在 JavaScript promise 字符串的 .then 函数中调用带参数的函数?

python - AWS Chalice所需的AWS IAM策略

javascript - 从 AWS lambda@edge 访问原始 URL

javascript - 在 Node.js/Express 中为 Sequelize.Create 触发两次 Ajax POST 请求

javascript - 使用 Node.js 提供 Javascript 文件

node.js - 从 Node 导出函数时出现 ReferenceError

java - 如何使用 AEM 解析 org.apache.http.ssl?