【发布时间】:2021-08-13 00:24:47
【问题描述】:
有什么方法可以在代码级别捕获AWS lambda timed out 错误,以便我有机会在退出lambda 函数之前处理该错误?
【问题讨论】:
-
可能会有所帮助:
context.get_remaining_time_in_millis()(和节点/其他等效项)将为您提供剩余的执行时间
标签: amazon-web-services aws-lambda
有什么方法可以在代码级别捕获AWS lambda timed out 错误,以便我有机会在退出lambda 函数之前处理该错误?
【问题讨论】:
context.get_remaining_time_in_millis()(和节点/其他等效项)将为您提供剩余的执行时间
标签: amazon-web-services aws-lambda
虽然 lambda 环境不会触发“超时”事件,但您可以自己轻松完成。
每种语言都有一个由context 对象公开的函数
到get the remaining time in milliseconds。
您可以将它与您使用的任何语言的计时器功能结合使用,以确保您在超时之前收到通知。
例如(节点):
function handler(event, context, callback) {
const timer = setTimeout(() => {
console.log("oh no i'm going to timeout in 3 seconds!");
// &c.
}, context.getRemainingTimeInMillis() - 3 * 1000);
try {
// rest of code...
} finally {
clearTimeout(timer);
}
callback(null, result);
}
【讨论】:
context 对象的示例 docs.aws.amazon.com/lambda/latest/dg/python-context.html 感谢 @thomasmichaelwallace 为我指明了正确的方向。
改用内置的Promise.race() 函数:
module.exports.myFunction = async (event) => {
// your real task
const task = new Promise((resolve) => {
setTimeout(() => resolve({ statusCode: 200, message: 'Task finished.' }), 1000);
})
// add a new "task": timeout
const timeout = new Promise((resolve) => {
setTimeout(() => resolve({ statusCode: 504, message: 'Sorry, your task timed out!' }), 200);
})
// start them synchronously
const res = await Promise.race([task, timeout]);
return res;
};
我想在这里分享我的解决方案:
假设我有一个 Lambda 处理函数,我设置的超时限制是 15 分钟。
在这个函数中,我有一个名为 work() 的异步函数,它可能需要 15 分钟以上的时间。
要从 Lambda 捕获超时错误,我的方法是:
我创建了一个名为timeout() 的新异步函数,该函数仅在 14.9 分钟后返回。
我让work()和timeout()函数同时启动,如果work()可以在14.9分钟内完成,那么work()比timeout()更早返回,否则timeout()更早返回。
您可以通过此图更轻松地看到它:
这正是 race() 操作员对 rxjs 所做的事情。
下面是使用rxjs实现这个想法的代码:
module.exports.myFunction = async (event) => {
function task() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('finished!');
}, 15 * 60 * 1000);
});
}
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('timeout!');
}, 14.9 * 60 * 1000);
});
}
const res = await new Promise((resolve, reject) => {
race(from(task()), from(timeout()))
.subscribe(msg => {
resolve(msg);
})
});
return { res };
};
【讨论】: