我有一个调用几个tasklet的POST
方法。这些tasklet确实有产量,我的代码中确实有一些x.put_async()
。所以我不希望它在所有异步内容完成之前返回。所以我装饰了所有的tasklet,它们只是@ndb.tasklet
的小函数。此外,除了POST
方法之外,我还有:
@ndb.toplevel
def post(self):
然而,在documentation中声明:
但是如果处理程序方法使用yield,那么该方法仍然需要 包装在另一个装饰器中,@ ndb.synctasklet;否则,它会 停止执行收益而不是完成。
确实我的方法有收益率。它已经包含在@ ndb.tasklet中。我是否用@ ndb.synctasklet替换它或者我同时使用它们(如果是这样,我将如何使用它们)?
另外,请参阅this thread,它具有一定的相关性。我也注意到一个问题,我的请求将返回没有任何输出,但是不可重现。它每15分钟左右就会持续使用。我只有app = ndb.toplevel(webapp2.WSGIApplication([..])
,但现在我已将@ndb.toplevel
添加到主POST
方法,但问题仍然存在。
我是否应该将@ndb.tasklet
放在仅有put_async()
的方法之上? (为了安全起见,我应该把它放在每个方法的顶部吗?这有什么缺点?)
答案 0 :(得分:10)
关于处理程序并使用@ndb.toplevel和@ndb.synctasklet: 我理解它的方式是你需要在处理程序上使用@ ndb.synctasklet和@ ndb.toplevel。所有子tasklet只需要@ ndb.tasklet装饰器。 e.g。
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实际上是一个synctasklet:
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.
"""
在处理程序中运行带有yield并用@ ndb.toplevel修饰的小测试似乎仍然有效,并且似乎可以从处理程序中删除@ ndb.synctasklet。
关于是否应该在调用put_async()的方法中包含@ ndb.tasklet: 如果你没有屈服于put_async(),那么你不需要在周围的方法中包含@ ndb.tasklet(@ ndb.toplevel将处理从put_async()获取结果)