2013-04-04 26 views
7

documentation如何理解appengine ndb.tasklet?

的NDB tasklt被一段代码可能与其他 代码同时运行。如果你写一个tasklet,你的应用程序可以使用它很多 就像它使用异步NDB函数:它调用tasklet,其中 返回一个Future;之后,调用Future的get_result()方法得到 的结果。

该文件中的解释和示例对我来说真的很喜欢魔术。 我可以使用它,但很难正确理解它。

例如:

  1. 我可以把任何类型的代码的函数里面,装饰它作为ndb.tasklet?之后将其用作异步函数。或者它必须是appengine RPC?
  2. 这种装饰工具是否也适用于我的电脑?
  3. 是不是一样tasklet for pypy

回答

14

如果你看看在未来的实现,它非常可比什么发电机是蟒蛇。实际上,它使用相同的yield关键字来实现它所做的功能。请阅读intro comments on the tasklets.py进行一些说明。

当您使用@tasklet装饰器时,它会创建一个Future并等待包装函数的值。如果该值是一个生成器,它将Future添加到事件循环中。当您在Future上yield时,事件循环会遍历所有排队的期货,直到您所需的期货已准备就绪。这里的并发性是,每个Future将执行其代码,直到它返回(使用raise ndb.Return(...)或函数完成),抛出异常,或者再次使用yield。我想在技术上,你可以在代码中使用yield来停止执行该函数,以便让事件循环继续运行其他期货,但是我认为这样做不会有多大帮助,除非你真的有一个聪明的用例。

回答您的问题:

  1. 技术上是可以的,但它不会异步运行。当您使用@tasklet装饰非屈服函数时,它的Future值将在您调用该函数时进行计算和设置。也就是说,当你调用它时,它会贯穿整个函数。如果你想实现异步操作,你必须在yield上进行异步工作。通常在GAE中,它将一直工作到RPC调用。

  2. 如果通过在PC上工作,您的意思是开发应用程序服务器像GAE那样实现tasklets/Future,然后是,尽管devappserver2(现在是新SDK中的默认值)更准确。实际上,如果本地RPC调用在使用期货时并行运行,我实际上并不是100%确定的,但是有一个eventloop正在通过期货进行调整,无论其本地还是在生产中。如果你想在你的其他非GAE代码中使用Future,那么我认为你会更好使用Python 3.2's built-in future(或找到一个backport here

  3. 有点,它不是一个简单的比较。看看documentation here。这个想法有些相同(调度器可以和事件回调相比较),但是低级实现大不相同。