如何在Google Cloud Functions中处理Python函数中的线程?

时间:2019-05-12 19:51:33

标签: python google-cloud-functions

我正在使用Google Cloud Functions运行一个Python函数,该函数已被我的Facebook Messenger机器人击中。 Facebook Messenger有一个怪异的要求:

  

当您收到一个webhook事件时,您必须始终返回200 OK HTTP响应。 Messenger平台将每20秒重新发送一次webhook事件,直到收到200 OK响应。未能返回200 OK可能会导致Messenger平台取消订阅您的Webhook。

换句话说,我有20秒的时间从我的云函数返回200 OK响应。问题是我实际上需要使用requests.post将从消息中接收到的数据发送到另一个API,并且基本上不能保证将花费少于20秒的时间。因此,理想情况下,我想使用线程和多处理。我意识到Google不允许进行线程化。有什么方法可以处理这种情况?谢谢。

1 个答案:

答案 0 :(得分:1)

如果我的理解正确,我们有一个原始的REST调用者(Facebook),它在20秒或更短的时间内需要一个响应。但是,正在处理请求的函数希望调用可能需要20秒钟以上才能响应的服务。一种可能的解决方案是,即使在该Cloud Function中的代码逻辑完成之前,也可以返回原始Cloud Function发送的响应。假设您在Node.js中进行编码,则将响应对象传递给Cloud Function。您可以在Cloud Function主体中的此对象上调用send()和end(),然后 then 继续进行并执行其他长期运行的工作。如果您想将整个过程的成功标准返回给您的原始呼叫者,听起来我们的故事相矛盾。合同似乎说,响应必须在20秒以内,而工作可能需要20秒以上。因此,在所有情况下,您都无法明智地返回表示完整结果的响应。

如果您使用Python编写应用程序,那么故事就不那么容易了。利用Python的云函数基于flask,并通过flask调用了(您提供的)Python函数。从此函数返回的数据是返回给调用方的数据。如果我们想早点回来,然后再做其他工作,则here中描述了一种方法。不幸的是,我们似乎无法利用这个故事,因为Cloud Functions拥有并管理Flask环境,而且我们没有合法的方式来添加其他处理程序。

我想到的另一个主意是让现在在Cloud Functions中运行的Facebook调用的Python代码执行一个Google Pub / Sub发布请求,以传递需要传递的数据。该发布将立即返回,然后您可以从Cloud Function快速返回并满足原始请求。然后,已发布的消息可用于触发第二个云功能,该功能可能需要花很长时间才能完成。

另一个想法是根本不使用云功能。您使用Cloud Functions实现无服务器编码的可能性很高,而不必担心扩展注意事项。现在提供了一个新功能(从Next 19开始),称为Cloud Run,它允许您创建一个可以运行自己的Flask python应用程序的Docker容器,然后您将完全控制环境。看来我们所拥有的是一种权衡。我们拥有Cloud Function,它提供了一种用于处理绝大多数REST请求的超快速机制...但是,如果我们需要专业化(必须在20秒或更短的时间内做出响应并进行后续工作),则Cloud Function可能已经提示我们想要实现一些自定义处理会成为一个障碍。