tornado.web.RequestHandler.render_string()如何在不阻塞整个应用程序的情况下加载模板?

时间:2016-11-08 14:36:19

标签: python html tornado template-engine coroutine

我正在使用render_string()从Tornado中的协程加载模板,我想到render_string()不是协程。因此我们从协同程序访问磁盘,但我们不会产生任何未来。我想知道它是如何工作的,如果它阻止了应用程序。

1 个答案:

答案 0 :(得分:0)

确实,第一次从磁盘读取给定模板时,它会阻止Tornado的事件循环:

class Loader(BaseLoader):
    def _create_template(self, name):
        path = os.path.join(self.root, name)
        with open(path, "rb") as f:
            template = Template(f.read(), name=name, loader=self)
            return template

这个初始加载可能很快,因为模板可能只有几千字节并且已经加载到机器的内存中文件系统缓存中。同一个Tornado进程对同一模板的后续访问将在Tornado中自动缓存:

class BaseLoader(object):
    def load(self, name, parent_path=None):
        """Loads a template."""
        name = self.resolve_path(name, parent_path=parent_path)
        with self.lock:
            if name not in self.templates:
                self.templates[name] = self._create_template(name)
            return self.templates[name]

因此,Tornado将文件系统访问权限推迟到线程似乎不值得。

通常在Python异步框架中,您将看到并非所有I / O都是异步执行的 - 快速且可预测的阻塞操作(如访问文件或MySQL查询)可能无法长时间阻止循环而无法担心。重要的是,在事件循环中安排长期或不可预测的操作,如调用远程HTTP服务。