Я загружаю шаблоны из сопрограммы в Торнадо, используя render_string()
, и мне пришло в голову, что render_string()
не является сопрограммой. Таким образом, мы получаем доступ к форме диска в сопрограмме, но мы не даем никаких фьючерсов. Интересно, как это работает, и если оно блокирует приложение или нет.Как tornado.web.RequestHandler.render_string() загружает шаблон без блокировки всего приложения?
ответ
Это правда, первый раз данный шаблон считывается с диска, он блокирует Торнадо в цикл событий:
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
Эта начальная нагрузка, вероятно, быстро, так как шаблон, скорее всего лишь несколько килобайт и уже загружается в кеш файловой системы в памяти устройства. Последующие доступы одного и тот же шаблона по тому же процессу Торнадо кэшируются в самом Торнадо:
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 вы увидите, что не все операции ввода-вывода выполняются асинхронно - быстрые и предсказуемые операции блокировки, такие как доступ к файлу или запрос MySQL, могут не блокировать цикл достаточно долго, чтобы беспокоиться. Важно то, что в цикле событий запланированы длинные или непредсказуемые операции, такие как вызов удаленного HTTP-сервиса.