龙卷风和concurrent.futures.Executor

时间:2015-06-08 21:13:56

标签: asynchronous tornado future

我正在学习异步和Torando以及挣扎。首先,可以在Tornado中使用执行者类吗?

以下示例我正在创建一个websocket,当收到消息时,我想将check()作为后台的另一个进程运行。这是一个人为的例子,仅仅是为了我的学习。 INSIDE或AFTER都没有打印出来。如果我们有这个执行器类,为什么我们需要像Motor这样的异步特定包呢?

同样在我看过Torando的所有例子中,@ gen.coroutine总是在我的例子中扩展tornado.web.RequestHandler的类上完成我正在使用tornado.websocket.WebSocketHandler可以@gen.coroutine也可以在这门课内使用吗?

最后,任何人都可以推荐有关此主题的书籍或深入教程吗?我买了“龙卷风简介”,但它有点过时,因为它使用了tornado.gen.engine。

def check(msg):

   time.sleep(10)
   return msg

class SessionHandler(tornado.websocket.WebSocketHandler):
   def open(self):
      pass

   def on_close(self):
      pass


   # not sure if i needed this decorator or not? 
   @tornado.web.asynchronous
   def on_message(self,message):
      print("INSIDE")

      with concurrent.futures.ProcessPoolExecutor() as executor:
          f=executor.submit(check,"a")
          result = yield f
      print("AFTER")

1 个答案:

答案 0 :(得分:0)

要使用yield,您必须使用@tornado.gen.coroutine(或@gen.engine)。 @tornado.web.asynchronousyield的使用无关,通常仅用于基于回调的处理程序(@asynchronous仅适用于常规处理程序,而不适用于websockets)。更改装饰器,你应该看到你的打印语句运行。

为什么有人会编写像Motor这样的异步库而不是像这样使用执行程序?为了表现。线程或进程池比异步执行相同的操作要昂贵得多(主要是在内存方面)。当你需要一个没有异步对应的库时,使用执行程序没有错,但如果它可用,那么使用异步版本会更好(如果性能很重要,那么在需要时写一个异步版本。)

另请注意,ProcessPoolExecutor可能很棘手:提交给执行程序的所有参数都必须是可选择的,这对于大型对象来说可能很昂贵。在大多数情况下,我建议使用ThreadPoolExecutor,只需要包装同步库。