Часть 1: Пусть получат вложенные торнадо (ы)
Чтобы найти нужную вам информацию, следуйте приведенным ниже инструкциям, начните с того, что описано в примечаниях к выпуску IPython 7
В частности, он укажет вам больше информации об асинхронных и ожидающих разделах в документации и этом обсуждении ,
которые предлагают использовать nest_asyncio .
Суть заключается в следующем:
- A) либо вы обманываете python для запуска двух вложенных циклов событий. (что делает nest_asyncio)
- B) Вы запланируете сопрограммы в уже существующем цикле событий. (Я не уверен, как это сделать с торнадо)
Я почти уверен, что вы все это знаете, но я уверен, что другие читатели это оценят.
К сожалению, нет способов сделать его полностью прозрачным для пользователей - хорошо, если вы не управляете развертыванием, как на jupyterhub, и не можете добавить эти строки в сценарии запуска IPython, которые автоматически загружаются. Но я думаю, что следующее достаточно просто.
import nest_asyncio
nest_asyncio.apply()
# rest of your tornado setup and start code.
Часть 2: Gotcha Синхронный кодовый блок eventloop.
Предыдущий раздел посвящен только запуску приложения торнадо. Но обратите внимание, что любой синхронный код заблокирует EventLop ; таким образом, при запуске print(requests.get("http://localhost:8000"))
сервер будет работать не так, как вы блокируете цикл событий, который будет перезапущен только после завершения выполнения кода, который ожидает перезапуска цикла событий ... (понимание, что это упражнение, оставленное читателю ). Вам нужно либо выпустить print(requests.get("http://localhost:8000"))
из другого ядра , либо использовать aiohttp.
Вот как использовать aiohttp аналогично запросам.
import aiohttp
session = aiohttp.ClientSession()
await session.get('http://localhost:8889')
В этом случае, поскольку aiohttp не блокирует, все будет работать правильно. Здесь вы можете увидеть дополнительную магию IPython, где мы автоматически определяем асинхронный код и запускаем его в текущем цикле событий.
Классным упражнением может быть запуск request.get
в цикле в другом ядре и запуск sleep(5)
в ядре, где работает торнадо, и мы видим, что мы прекращаем обработку запросов ...
Часть 3: Отказ от ответственности и другие маршруты:
Это довольно хитроумно , и я бы посоветовал не использовать его в производстве и предупредить ваших пользователей, что это не рекомендуемый способ действий.
Это не полностью решает ваш случай, вам нужно будет запустить вещи не в главном потоке, что, я не уверен, возможно.
Вы также можете попробовать поиграть с другими бегунами петель, такими как trio и curio ; они могут позволить вам делать вещи, которые вы не можете по умолчанию с помощью asyncio, например, вложения, но здесь будут драгуны . Я настоятельно рекомендую трио и несколько постов в блоге о его создании , особенно если вы учите асинхронности.
Наслаждайтесь, надеюсь, что это помогло, и, пожалуйста, сообщайте об ошибках, а также о том, что сработало.