Использование @ndb.tasklet или @ndb.synctasklet в Google App Engine
У меня есть метод POST
, который вызывает несколько тарелок. Эти цепочки имеют урожайность в них, и у меня есть код x.put_async()
в моем коде. Поэтому я не хочу, чтобы он возвращался, прежде чем все асинхронные вещи будут сделаны. Поэтому я украсил все мои талисманы, которые представляют собой небольшие функции с @ndb.tasklet
. Кроме того, поверх моего метода POST
у меня есть:
@ndb.toplevel
def post(self):
Однако в документации говорится:
Но если метод обработчика использует выход, этот метод все еще должен быть завернутый в другой декоратор, @ndb.synctasklet; в противном случае прекратите выполнение с выходом и не закончите.
Действительно, мой метод имеет выход. Он уже завернут в @ndb.tasklet. Я заменяю это на @ndb.synctasklet или я использую оба (если так, как бы я использовал оба)?
Также см. этот поток, который имеет некоторое значение. Я тоже заметил проблему, когда мой запрос возвращался без вывода, но не воспроизводится. Это происходит каждые 15 минут постоянного использования. У меня был только app = ndb.toplevel(webapp2.WSGIApplication([..])
, но теперь я добавил @ndb.toplevel
в основные методы POST
, но проблема все еще сохраняется.
Должен ли я помещать @ndb.tasklet
поверх методов, которые имеют только put_async()
тоже? (Должен ли я помещать его поверх каждого метода, чтобы быть в безопасности? Каковы недостатки этого?)
Ответы
Ответ 1
Относительно обработчика и использования @ndb.toplevel и @ndb.synctasklet:
Я понял, что вам нужно использовать как обработчик @ndb.synctasklet, так и @ndb.toplevel. Все подэлементы нужны только декоратору @ndb.tasklet. например.
class Foo(ndb.Model):
name = ndb.StringProperty()
@ndb.tasklet
def my_async(self):
....
#do something else that yields
raise ndb.Return("some result")
@ndb.toplevel
@ndb.synctasklet
def post(self):
foo = Foo(name="baz")
yield foo.put_async()
yield foo.my_async()
....
Однако. глядя на source, похоже, что @ndb.toplevel на самом деле является синтаксической буквой:
def toplevel(func):
"""A sync tasklet that sets a fresh default Context.
Use this for toplevel view functions such as
webapp.RequestHandler.get() or Django view functions.
"""
Выполнение небольшого теста с выходами в обработчике и украшение с помощью @ndb.toplevel все еще работает, и кажется, что вы можете удалить @ndb.synctasklet из обработчика.
Относительно того, следует ли вам включать @ndb.tasklet в методы, вызывающие put_async():
Если вы не уступаете put_async(), вам не нужно включать @ndb.tasklet в окружающий метод (@ndb.toplevel будет обрабатывать результаты с put_async())