【问题标题】:Is there any way to catch AWS lambda timed out error in code level?有没有办法在代码级别捕获 AWS lambda 超时错误?
【发布时间】:2021-08-13 00:24:47
【问题描述】:

有什么方法可以在代码级别捕获AWS lambda timed out 错误,以便我有机会在退出lambda 函数之前处理该错误?

【问题讨论】:

  • 可能会有所帮助:context.get_remaining_time_in_millis()(和节点/其他等效项)将为您提供剩余的执行时间

标签: amazon-web-services aws-lambda


【解决方案1】:

虽然 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);
}

【讨论】:

  • 确保?我不明白这怎么能可靠地“捕捉”超时,如果你使用一个需要 5 秒来完成某项任务的阻塞第三方库怎么办?
  • 是的——这绝对是一个边缘案例。如果您正在做一些非常长且同步的事情,那么您将永远无法检测到超时。但是,至少根据我的经验,这些在 node.js 中并不常见。例如,所有节点的标准库都是异步的(屈服控制),所有的 aws-sdk 也是如此。在不屈服于事件循环的慢速函数的情况下,我认为你永远无法检测到超时,除非编辑函数以定期检查。
  • 是的,我认为您对节点的看法是正确的,在我的情况下,不幸的是,一切都是在 python 中完成的,我想每 15 分钟检查一次尚未关闭其流程的其他任务,然后重试或分解成更小的任务是一种解决方案
  • @Mojimi 您可以修改上述内容,改为在结束前 X 秒抛出异常。因此,您可以捕获自己的异常并进行处理,而不是尝试在 Lambda 级别捕获一些异常。至少它可以让你优雅地处理你的长时间运行的过程。
  • 对于 Python 用户,这里是 context 对象的示例 docs.aws.amazon.com/lambda/latest/dg/python-context.html 感谢 @thomasmichaelwallace 为我指明了正确的方向。
【解决方案2】:
更新:

改用内置的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 };
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2020-09-20
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多