我碰到这个结果,当在一堆异步查询上执行ndb.Future.wait_all(futures)
时,GAE Ndb异步查询上的运行时错误无法设置两次。
像这样的东西:
futures = []
for item in items:
item._future_get = MyEntity.query(...).get_async()
futures.append(item._future_get)
ndb.Future.wait_all(futures)
# ...
在
wait_all
上失败,结果不能设置两次SO上无处提及此错误消息。 Google自2011年以来已有2-3次提及它,但没有明确的解释。
更多信息:
项目是上一次获取的ndb实体。但是它们在这里并不重要(至少在我看来),因为查询是在MyEntity上执行的。我习惯将 future 以这种方式附加到与之相关的对象上,因此在完成所有操作后更容易进行整理。
堆栈跟踪:
File "/home/my_project/app/main/admin/my_module.py", line 166, in admin_base_cleanup_details ndb.Future.wait_all(futures)
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 350, in wait_all ev.run1()
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/eventloop.py", line 235, in run1 delay = self.run0()
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/eventloop.py", line 197, in run0 callback(*args, **kwds)
INFO 2016-04-26 08:40:04,152 module.py:808] default: "GET /admin/cleanup/details?mode=status HTTP/1.1" 500 -
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 475, in _on_future_completion self._help_tasklet_along(ns, ds_conn, gen, val)
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 386, in _help_tasklet_along self.set_result(result)
File "/usr/lib/python2.7/google_appengine/google/appengine/ext/ndb/tasklets.py", line 265, in set_result
raise RuntimeError('Result cannot be set twice.')
RuntimeError: Result cannot be set twice.
一些精度:
我发现它与另一个线程的并发性有关。该网页通过ajax调用启动了2个请求:一个请求使用一些异步调用进行更新查询,这将花费相当多的时间,而另一个请求(例如定期状态更新)则更快,但也需要异步调用。是后者失败了,不总是失败,但经常失败。从那时起,我避免了两个请求重叠,并且它停止失败。仍然看起来像是个错误,因为不禁止重叠的请求。
最佳答案
您正在使用“异步返回第一个查询结果”的get_async(),而您可能应该使用fetch_async()来获取Future。
https://cloud.google.com/appengine/docs/python/ndb/queryclass#Query_get_async
关于python - GAE NDB "Result cannot be set twice"错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36849031/