GAE NDB Ошибка "Результат не может быть установлен дважды"
Я ударил этот результат не может быть установлен дважды Ошибка времени выполнения на асинхронных запросах GAE Ndb при выполнении ndb.Future.wait_all(futures)
на кучу асинхронных запросов.
Что-то вроде этого:
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 имеет 2-3 упоминания об этом, начиная с 2011 года, и без четких объяснений.
Больше информации:
элементы ndb сущностей из предыдущей выборки. Но они на самом деле не имеют значения (по крайней мере, я так думаю), поскольку запрос выполняется в MyEntity. Я привык прикреплять фьючерсы к объекту, к которому они относятся, таким образом, так что легче разобраться, когда все закончится.
Трассировка стека:
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.
Еще немного точности:
Да, это происходит как в GAE, так и в локальной системе разработки.
Нет, это не терпит неудачу каждый раз, но достаточно часто.
Я обнаружил, что это связано с параллелизмом из другого потока. Веб-страница запустила 2 запроса через ajax-вызовы: один для запроса на обновление с некоторыми асинхронными вызовами, который займет довольно много секунд, а другой - для периодического обновления статуса, более быстрый, но также с асинхронными вызовами. Это последнее не удалось, не всегда, но очень часто. С тех пор я избегал совмещения двух запросов, и это перестало давать сбой. Это все еще похоже на ошибку, поскольку перекрывающиеся запросы не являются чем-то запрещенным.
1 ответ
Вы используете get_async(), который "асинхронно возвращает первый результат запроса", тогда как вы, вероятно, должны использовать fetch_async(), чтобы получить Future.
https://cloud.google.com/appengine/docs/python/ndb/queryclass