【问题标题】:Should I wait for each ndb.Model.put_async() in Google App Engine request?我应该等待 Google App Engine 请求中的每个 ndb.Model.put_async() 吗?
【发布时间】:2015-10-02 08:43:31
【问题描述】:

我不确定如何在 Google App Engine 中处理异步操作。你能帮我看看这段代码吗?

我要异步放置实体:

class Thing(ndb.Model):
  pass

entity = Thing()
future = entity.put_async()

# hundred of code lines of other async to parallelize

但我不确定是否应该在处理程序结束之前等待这个 put?

我应该完成我的代码以保持数据一致吗?

future.wait()

也许我的问题看起来微不足道,但我想避免来自意外行为的随机错误。我读了https://cloud.google.com/appengine/docs/python/ndb/futureclass,但在这里没有找到好的答案。

https://cloud.google.com/appengine/docs/python/ndb/async 也一样。

【问题讨论】:

  • 如果要等待异步方法完成,为什么还要使用它?
  • @TimCastelijns 因为我想使用put_async() 而不是put()。代码被简化。不要以为我不知道如何使用put() 假设我必须使用put_async() 并且跳过了数百行代码。

标签: python google-app-engine google-cloud-datastore app-engine-ndb


【解决方案1】:

你可以使用 ndb.toplevel()

From the docs:

在这个例子(和你的代码)中,调用 future.get_result 有点傻:应用程序从不使用 NDB 的结果。该代码只是为了确保在 NDB put 完成之前请求处理程序不会退出;如果请求处理程序退出得太早,则 put 可能永远不会发生。为方便起见,您可以使用 @ndb.toplevel 装饰请求处理程序。这告诉处理程序在其异步请求完成之前不要退出。这反过来又可以让您发送请求而不必担心结果。

您可以将整个 WSGIApplication 指定为 ndb.toplevel。这确保了每个 WSGIApplication 的处理程序在返回之前等待所有异步请求。 (它不会“顶层”所有 WSGIApplication 的处理程序。)

例子:

app = ndb.toplevel(webapp2.WSGIApplication(routes=routes, debug=True))

【讨论】:

  • 这是一个很好的答案,我会珍惜它,因为它展示了对 ndb 异步操作流程的深刻洞察。
【解决方案2】:

如果你想处理任何失败,你应该等待完成。

如果你能承受失去一些实体的代价(通常比例很小,但如果数据中心问题可能会在一段时间内急剧增长到 100%),你可以触发异步操作并忘记它.虽然有一个隐藏的问题 - 我现在找不到链接,但我记得有人告诉 GAE 将等待所有期货完成,然后再向客户返回响应。这是需要测试的东西。

您可以在列表中累积期货,然后在流程结束时调用Future.wait_all(futures)。放入 try:except 块,当得到每个 future 的异常检查状态并根据需要进行处理。

【讨论】:

  • 我目前正在按最终请求执行Future.wait_all(futures),无需处理故障。数据并不重要。我将检查处理程序是否完成了一些异步清理 - 它可能应该在某处注册所有期货。
  • 请注意,GAE 在本地和 PROD 环境中的异步操作行为可能有所不同。在我们对本地环境的单元测试中,我们必须收集并等待所有异步操作,而在 PROD 中它工作得很好射击和遗忘。
  • 是的,应该认为开发服务器不是生产服务器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
相关资源
最近更新 更多