异步和解析的问题
Trouble with async and Parse
我正在使用 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.");
}
});
我想要(和期望)的是得到输出 "Updating subscriptions... Got subscriptions. Wrapping up."
实际发生的是我看到 "Updating subscriptions...",仅此而已。看起来该函数实际上并没有在等待异步调用,and/or Lambda 正在提前终止进程。
有人知道我做错了什么吗?
我已经解释了为什么它不是错误,而是有意设计的。因此,您可以 运行 比 httpRequest 超时时间更长的事情。
如果您查看代码 here,您会发现 handleCloudJob() 函数竭尽全力将作业执行与请求生命周期隔离开来。这是设计,不是错误。
现在,让我们看看它在 lambda 中是如何工作的:
- 请求进来
- handleCloudJob() 被调用
- 作业设置为running
- 我们调用process.nextTick() 入队作业有效工作
- 我们 return 作业状态 ID。
- 响应与 jobID 一起发送
- 工作开始,由 process.nextTick 排队
... > 时间流逝
- 作业完成
- jobStatus 获得 updated
现在想象一下我们没有这样做:
at if 而不是 6。发送响应,我们 'awaiting' 完成了工作,就像你建议的那样
会发生什么:
- 可能会达到套接字超时(30 秒),因为作业 'long'
- 连接将被关闭
- 无法获取作业 ID。
现在在您的 lambda 环境中发生了什么:
- 入队在第 4 步完成,
- 在第 6 步发送响应
- 响应被发送到客户端
- lambda 环境被破坏。
这是预期的行为。
还能再好点吗?也许吧,但这需要一个完全不同的作业执行环境。基本上是等待在后台执行很长时间的消息的工作人员(因此不是前端 lambda)
在 lambda 常见问题解答中指出 default timeout is 3s 并且可以扩展到最多 300 秒。所以默认情况下 lambda 不适合 运行 作业。
虽然我理解你的挫败感,而且这对 'you' 没有意义,但这都是设计使然。
即使我们交换了解析服务器上的实现,它也不适合 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.");
}
});
我想要(和期望)的是得到输出 "Updating subscriptions... Got subscriptions. Wrapping up."
实际发生的是我看到 "Updating subscriptions...",仅此而已。看起来该函数实际上并没有在等待异步调用,and/or Lambda 正在提前终止进程。
有人知道我做错了什么吗?
我已经解释了为什么它不是错误,而是有意设计的。因此,您可以 运行 比 httpRequest 超时时间更长的事情。
如果您查看代码 here,您会发现 handleCloudJob() 函数竭尽全力将作业执行与请求生命周期隔离开来。这是设计,不是错误。
现在,让我们看看它在 lambda 中是如何工作的:
- 请求进来
- handleCloudJob() 被调用
- 作业设置为running
- 我们调用process.nextTick() 入队作业有效工作
- 我们 return 作业状态 ID。
- 响应与 jobID 一起发送
- 工作开始,由 process.nextTick 排队 ... > 时间流逝
- 作业完成
- jobStatus 获得 updated
现在想象一下我们没有这样做:
at if 而不是 6。发送响应,我们 'awaiting' 完成了工作,就像你建议的那样
会发生什么:
- 可能会达到套接字超时(30 秒),因为作业 'long'
- 连接将被关闭
- 无法获取作业 ID。
现在在您的 lambda 环境中发生了什么:
- 入队在第 4 步完成,
- 在第 6 步发送响应
- 响应被发送到客户端
- lambda 环境被破坏。
这是预期的行为。
还能再好点吗?也许吧,但这需要一个完全不同的作业执行环境。基本上是等待在后台执行很长时间的消息的工作人员(因此不是前端 lambda)
在 lambda 常见问题解答中指出 default timeout is 3s 并且可以扩展到最多 300 秒。所以默认情况下 lambda 不适合 运行 作业。
虽然我理解你的挫败感,而且这对 'you' 没有意义,但这都是设计使然。
即使我们交换了解析服务器上的实现,它也不适合 lambda 到 运行 作业。