async 和 Parse 的问题

Dan*_*ell 1 node.js parse-platform aws-lambda

我正在使用 Parse Server 并且在异步函数未按预期运行时遇到问题。我在 AWS Lambda 上的 Node.js 8.10 上运行它。这是我的函数的(非常简化的)版本:

Parse.Cloud.job("updateSubscriptions", async (req, res) => {
  try {
    winston.info("Updating subscriptions...");

    var Subscription = Parse.Object.extend("Subscription");
    var query = new Parse.Query(Subscription);

    await query.find().then(
      function () {
        winston.debug("Got subscriptions.");
      },
      function(error) {
        winston.error("Error querying subscriptions.");
      }
    );
    winston.debug("Wrapping up.");
  } catch (e) {
    winston.error("Uh oh.");
  }
});
Run Code Online (Sandbox Code Playgroud)

我想要(并期望)的是获得输出“更新订阅...获得订阅。结束。”

实际发生的是我看到“正在更新订阅...”,仅此而已。看来该函数实际上并未等待异步调用,和/或 Lambda 提前终止了该进程。

有谁知道我在这里做错了什么?

flo*_*art 5

我已经解释了为什么它不是设计和故意的错误。所以你可以运行比 httpRequest 超时更长的时间。

如果您查看此处的代码您会发现 handleCloudJob() 函数将作业执行与请求生命周期隔离开来。这是设计使然,不是错误

现在,让我们看看它在 lambda 中是如何工作的:

  1. 请求进来
  2. handleCloudJob() 被调用
  3. 作业设置为运行
  4. 我们调用 process.nextTick() 将工作有效工作入队
  5. 我们返回工作状态 ID。
  6. 响应与 jobID 一起发送
  7. 工作开始,由 process.nextTick 排入队列 ... > 时间过去了
  8. 工作完成
  9. jobStatus 得到更新

现在想象一下我们没有这样做:

在 if 而不是 6. 发送响应,我们正在“等待”工作,就像你建议的那样

会发生的事情是:

  • 可能会达到套接字的超时(30 秒),因为作业很“长”
  • 连接将被关闭
  • 无法获得作业 ID。

现在在你的 lambda 环境中会发生什么:

  • 入队在第 4 步完成,
  • 在第 6 步发送响应
  • 响应被发送到客户端
  • lambda 环境被破坏。

这是预期的行为。

可以更好吗?也许吧,但这需要一个完全不同的作业执行环境。基本上是等待在后台长时间执行的消息的工作人员(因此不是前端 lambdas)

在 lambdas 常见问题解答中声明默认超时为 3 秒,并且可以扩展到最大 300 秒。所以默认情况下 lambda 不适合运行作业。

虽然我理解你的挫败感,而且这对“你”来说毫无意义,但这都是有意为之。

即使我们在 parse-server 上交换了实现,它也不适合 lambdas 来运行作业。