当前位置: 首页 > 面试题库 >

在Tornado异步处理程序中使用简单的python生成器作为协同例程?

封景曜
2023-03-14
问题内容

我有一个python生成器函数,可以生成文本块。我想gettornado.web.RequestHandler子类编写一个方法,该方法将遍历生成器,并随即将大块写入响应。

由于这是Tornado,并且由于生成器可能要花一秒钟的时间来处理,所以我认为最好使处理程序异步,使用此生成器作为协程并将控制权在每个块之后传递给IOLoop。但是,我无法做到这一点。

这是我的示例(阻止)代码:

class TextHandler(web.RequestHandler):
    @web.asynchronous
    def get(self, n):
        generator = self.generate_text(100000)
        # Clearly, this will block. How to make it asynchronous?
        for text in generator:
            self.write(text)

    def generate_text(n):
        for x in xrange(n):
            if not x % 15:
                yield "FizzBuzz\n"
            elif not x % 5:
                yield "Buzz\n"
            elif not x % 3:
                yield "Fizz\n"
            else:
                yield "%s\n" % x

如何使此处理程序异步工作?


问题答案:

这是您所描述内容的基本版本。为了避免阻塞,您可以通过回调函数将生成器传递给IOLoop。这里的技巧是因为您没有使用执行实际IO的进程,因此没有os级别的进程/文件处理程序可通过来添加到IOLoop中add_handler,您可以使用简单的add_callback调用并从回调函数中反复调用它来保持IOLoop回调队列中的函数,直到生成器完成为止。

import tornado.httpserver
import tornado.ioloop
import tornado.web

class TextHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        self.generator = self.generate_text(1000)
        tornado.ioloop.IOLoop.instance().add_callback(self.loop)

    def loop(self):
        try:
            text = self.generator.next()
            self.write(text)
            tornado.ioloop.IOLoop.instance().add_callback(self.loop)
        except StopIteration:
            self.finish()

    def generate_text(self, n):
        for x in xrange(n):
            if not x % 15:
                yield "FizzBuzz\n"
            elif not x % 5:
                yield "Buzz\n"
            elif not x % 3:
                yield "Fizz\n"
            else:
                yield "%s\n" % x

application = tornado.web.Application([
    (r"/text/", TextHandler),
])

http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()


 类似资料:
  • 本文向大家介绍简单介绍Python的Tornado框架中的协程异步实现原理,包括了简单介绍Python的Tornado框架中的协程异步实现原理的使用技巧和注意事项,需要的朋友参考一下 Tornado 4.0 已经发布了很长一段时间了, 新版本广泛的应用了协程(Future)特性. 我们目前已经将 Tornado 升级到最新版本, 而且也大量的使用协程特性. 很长时间没有更新博客, 今天就简单介绍下

  • 我的完成处理程序有问题。下面是一个带有完成处理程序的函数,位于一个实用程序文件中: 我在视图控制器中调用它 输出清楚地表明该函数在运行该块之前没有等待完成: 我如何解决这个问题?

  • 问题内容: 这是处理生成器中引发的异常的后续操作,并讨论了一个更一般的问题。 我有一个功能,可以读取不同格式的数据。所有格式都是面向行或记录的,每种格式都有一个专用的解析功能,可以作为生成器来实现。因此,主读取函数获得一个输入和一个生成器,该生成器从输入中读取其各自的格式并将记录传递回主函数: 哪里是这样的: 我面临的问题是,尽管可能引发异常(例如,从流中读取时),但它不知道如何处理它。负责处理异

  • 本文向大家介绍Python的Tornado框架异步编程入门实例,包括了Python的Tornado框架异步编程入门实例的使用技巧和注意事项,需要的朋友参考一下 Tornado Tornado 是一款非阻塞可扩展的使用Python编写的web服务器和Python Web框架, 可以使用Tornado编写Web程序并不依赖任何web服务器直接提供高效的web服务.所以Tornado不仅仅是一个web框

  • 在Tornado中,我们可以使用coroutine decorator作为Python生成器灵活地编写一个异步函数,其中每个yield语句返回给调度器,最后的raise/return向调用者返回一个值。但是,有没有任何方法可以向调用者返回一系列值,其中穿插着异步调用? 例如,如何启用此同步功能: …我可以这样称呼它: …进入Tornado中类似的异步函数?例如。: 我该怎么称呼它呢? 我可以想出一

  • 问题内容: 有人可以告诉我这段代码在做什么吗?无论如何,它只是打印“计数”。我只想要一个非常简单的素数生成器(没什么花哨的)。 问题答案: 有一些问题: 当计数不除以x时,为什么要打印计数?这并不意味着它是素数,仅意味着该特定x不会将其除 移至下一个循环迭代-但你确实想使用停止它 这是你的代码,其中包含一些修复程序,它仅输出质数: 有关更有效的质子生成,请参见其他人的建议,参见戊二烯筛。这是一个不