Фоновые задачи в Flask-SocketIO

У меня довольно простой вопрос, но я не нашел очень простого ответа: когда я должен использовать start_background_task() вместо запуска потока Python «обычно»? В документации Flask-SocketIO указано:

Эта функция возвращает объект, совместимый с классом Thread в стандартной библиотеке Python. Метод start() для этого объекта уже вызывается этой функцией.

В нем мало говорится о том, необходимо ли использовать это вместо инициализации и запуска потока для модуля threading.


person star8163264    schedule 15.06.2020    source источник


Ответы (1)


Причина существования start_background_task() заключается в том, что в зависимости от того, какой веб-сервер вы используете, изменяется модель потоков. Например, если вы используете eventlet или gevent, то фоновую задачу нужно запускать как гринлет, а не как экземпляр Thread.

Если вы используете start_background_task(), вам будет гарантировано, что будет использоваться объект задачи, совместимый с вашей средой.

person Miguel    schedule 16.06.2020
comment
Итак, если я использую eventlet, значит ли это, что мне вообще не следует использовать экземпляры Thread, или мне не следует использовать экземпляры Thread, когда я собираюсь запустить фоновую задачу, которая выполняет такие действия, как излучение? Другими словами, безопасно ли использовать экземпляр Thread для выполнения каких-либо операций ввода-вывода на сервере, совершенно не связанных с соединением клиент-сервер? - person star8163264; 17.06.2020
comment
Обычно приложение eventlet вообще не использует обычные потоки, потому что очень сложно заставить обычный поток взаимодействовать с сервером eventlet, не блокируя его. - person Miguel; 18.06.2020
comment
Итак, вы рекомендуете быть осторожным с тем, какие модули вы импортируете, на случай, если они также могут использовать экземпляры Thread? В моем случае мне было интересно, потому что у меня есть приложение, работающее только локально для меня, которое сохраняет данные в текстовую плитку, и у меня есть эта операция сохранения, происходящая в экземпляре Thread. Проблем не замечал, давно пользуюсь. Я также никогда не присоединяю этот поток к основному потоку. Я не уверен, что это имеет значение. Если это проблема, должен ли я передавать объект SocketIO любому другому пользовательскому модулю, который я создаю, если я хочу, чтобы этот модуль запускал фоновые задачи? - person star8163264; 18.06.2020
comment
Если ваш поток просто выполняет некоторую работу сам по себе и никогда не взаимодействует с остальной частью приложения, я думаю, это не вызовет проблем. В случае использования кода, который запускает потоки, eventlet предоставляет опцию исправления обезьяны, которая адаптирует класс Thread для использования гринлетов. См. eventlet.net/doc/patching.html. - person Miguel; 18.06.2020
comment
Что вы имеете в виду под общением с остальной частью приложения? Насколько я понимаю сейчас, если ваша задача будет общаться с клиентом, гринлет необходим. Но как насчет случая, когда вы берете данные из другого API/URL. Безопасно ли использовать обычный поток, если сам этот поток не будет отправлять данные клиенту напрямую? По сути, я хотел бы знать, когда абсолютно необходимо использовать гринлеты. - person star8163264; 18.06.2020
comment
На самом деле я только что просмотрел несколько тестовых примеров и обнаружил, что использование Thread поверх функции фоновой задачи socketio делает блокировку менее вероятной, даже если я испускаю данные в непрерывном цикле. Возможно, это выходит за рамки вопроса, который я задал, но я просто не совсем уверен, какие проблемы могут возникнуть при использовании модуля потоковой передачи. - person star8163264; 18.06.2020
comment
Связь, которую я упомянул, — это когда этому фоновому потоку необходимо каким-либо образом взаимодействовать с потоком событий. Если поток независим, то все должно быть в порядке. Если ему необходимо координировать или передавать данные на сторону eventlet, вы, вероятно, столкнетесь с проблемами. - person Miguel; 19.06.2020