【问题标题】:Call cloud functions without waiting for response无需等待响应即可调用云函数
【发布时间】:2020-04-18 01:36:42
【问题描述】:

在这里尝试使用云功能进行一些小技巧,但似乎无法弄清楚问题所在。

我目前正在使用 now.sh 来托管无服务器函数,并希望从另一个函数调用 1 个函数。假设我有 2 个函数声明为 fetchDatasetData。当调用setData 函数时,它会处理一些数据,然后调用fetchData 函数。

export const setData = async (req: Request, res: Response) => {
  await axios.post(
    fetchDataEndpointUrl,
    {
      params: {
        key,
      },
    },
  );

  return res.json({
    payload: true,
  });

}

上面的代码工作正常,但是完成整个操作所花费的时间将是 setData 函数调用 + fetchData 函数调用完成所花费的时间。我要做的是调用fetchData,而不必等待它完成基本上删除axios调用中的await。我试过删除await,但是当setData 通话结束时通话突然结束。有没有办法解耦这个动作而不必等待setData函数完成?

【问题讨论】:

  • 本质上setData是一个后台任务。我不确定now.sh 上的基础架构,但您通常会使用一些pub/sub 架构来实现它。我在GCP 上做过类似的事情
  • setData 是否接受 next 参数?也许在链的第一个砖块中返回响应,然后在单独的砖块中调用 axios 函数可以吗? more here
  • @shukar 考虑到这是一个无服务器架构,我认为通过网络传递 next 函数没有任何用途。
  • 我已经用 Firebase Cloud Functions 做过类似的事情,我会使用“触发”HTTPS 请求,它将预期的工作保存到 Cloud Firestore,触发 secondary Cloud Function 来执行长时间运行东西。这样做的好处是客户端还可以监听该 Firestore 文档的更新以获取结果

标签: javascript node.js typescript google-cloud-functions vercel


【解决方案1】:

您的问题的摘要似乎是,当您调用云函数时,您希望它能够向其调用者返回一个值,同时执行后台工作,例如调用另一个服务并等待响应。

当您将值返回给 Cloud Function 的调用者时,即是 Cloud Function 生命周期的结束。除了回报之外,您无法确定 Cloud Function 中的任何生命

这已记录在here

正文(部分)如下:

函数只能访问请求的资源(CPU 和内存) 在函数执行期间。代码在外部运行 执行周期不保证执行,可以停止 随时。因此,您应该始终表示您的结束 函数执行正确,避免运行超出它的任何代码。

问题的另一部分是,如果我们想让我们的云函数在我们不关心等待响应的情况下进行异步 REST 调用,该怎么办。我们能否在不等待嵌套 REST 调用完成的情况下从 Cloud Function 返回?

答案是也许,但这取决于被调用服务的性质以及我们如何调用它。要了解其中的细微差别,请记住 JavaScript 是一种单线程语言。没有多个执行线程。在我们的 JavaScript 应用程序中,一次只会发生一件事。如果我们进行异步 REST 调用并且不关心回复但(显然)确实关心请求已发送,那么我们需要在终止 Cloud Function 之前同步发送请求。如果我们开始使用库包而不深入研究它们的性质,这可能会变得很棘手。例如,一个 REST 调用可能包括:

  • 与合作伙伴的套接字连接
  • 出站请求的传输
  • 收到响应时的回调

在结束顶层云函数调用之前,我们需要绝对确定传输已经发生。此外,如果我们确实结束了顶级 Cloud Function 调用,那么很可能会降低用于响应的套接字。这可能会导致调用的 REST 服务出现异常,现在无法返回其 200 响应。

为了在我们不需要也不想等待响应的地方运行工作,GCP 为此提供了一个结构化的解决方案。它被称为“云任务”(参见Cloud Tasks)。在您的 Cloud Function 中,您将定义一个异步调用嵌套服务的请求,并将该请求交给 Cloud Tasks 执行。 Cloud Tasks 会确认收到执行请求,您现在可以放心,它会并且可以在最高级别返回。

【讨论】:

  • 浏览了文档,我其实不需要等待后台任务的响应,我只需要它自己触发和执行。考虑到这些是独立的云函数,从另一个调用一个不算作单独的云函数调用,为什么它被视为后台任务?
  • 我试图在答案中添加更多单词。我们可能还希望将 Cloud Tasks 视为答案中的一个组件。
  • @Kolban 我相信我们仍然需要等待 Cloud Tasks 确认收到。因此,如果我们调用的服务具有比“CloudTask Acknowledge”请求更长的 ping 时间,那么解决方法是有意义的,对吧?您认为这对于从 GCP 功能调用“第三方电子邮件服务”是否可行?
  • @Mehari ... 我想我们会调用 Cloud Tasks 来安排要执行的任务,并在完成 Cloud Function 调用之前等待对 Cloud Tasks 的调用完成。
猜你喜欢
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 2019-05-28
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多