Причина, по которой это работает с FLASK_DEBUG=0
, но не FLASK_DEBUG=1
, заключается в том, что приложение работает в основном потоке, когда он не находится в режиме отладки, но не запускается в основном потоке, когда находится в режиме отладки.
Соответствующий код находится в asyncio.events.BaseDefaultEventLoopPolicy.get_event_l oop:
def get_event_loop():
if (self._local._loop is None and
not self._local._set_called and
isinstance(threading.current_thread(), threading._MainThread)):
self.set_event_loop(self.new_event_loop())
if self._local._loop is None:
raise RuntimeError('There is no current event loop in thread %r.'
% threading.current_thread().name)
return self._local._loop
Событие l oop может быть создано только в главном потоке с текущей политикой события l oop: _UnixDefaultEventLoopPolicy
в моем случае. Обратите внимание, что _UnixDefaultEventLoopPolicy
подклассы BaseDefaultEventLoopPolicy
, но не переопределяет BaseDefaultEventLoopPolicy
.
Возможные решения:
- Создать новое событие l oop в текущем потоке
loop = asyncio.new_event_loop()
- Создание пользовательской политики l oop, которая позволяет
asyncio.get_event_loop()
создавать новое событие l oop в потоке, отличном от основного, путем переопределения метода events.AbstractEventLoopPolicy.get_event_loop
. Вероятно, самый безопасный способ сделать это - создать подкласс любой политики l oop, используемой вашей средой, и переопределить ее метод get_event_loop
, удалив проверку основного потока. Таким образом вы сохраняете все другие варианты поведения политики, хотя изменение может нарушить некоторые из этих вариантов поведения.
В любом случае вы создаете событие l oop для потока. Мой стандартный наклон к go для простоты, поэтому # 1.
Так почему же приложение не запускается в основном потоке в режиме отладки? Во-первых, в режиме отладки есть два процесса: сервер Flask и отладчик flask run
и python pydevd.py
соответственно. Основной поток каждого процесса имеет событие l oop, которое, среди прочего, облегчает связь между сервером приложений и отладчиком и порождает другой поток, в котором фактически выполняется приложение. Вы также увидите это поведение без включенного режима отладки, если приложение обслуживается многопоточным сервером приложений, например gunicorn или uwsgi.
Flask на самом деле не поддерживает asyncio
. Конечно, можно использовать его с Flask, но никаких гарантий относительно их совместимости не дается. См. Этот выпуск , а более конкретно: вопрос, упомянутый в его комментариях