Как запускать потоки и ждать их окончания, не блокируя сервер Django?
У меня проблема с Django. У меня есть функция, которая выполняет тяжелую обработку (манипулирование фреймами данных). Эта задача выполняется после отправки формы, содержащей необходимую информацию для запуска обработки, которая является тяжелой.
Я пытался создать поток для этой функции с помощью Threading. Проблема в том, что процесс хорошо отправляется в фон, чтобы не блокировать сервер, только вот появляется ошибка. Я думаю эта ошибка нормальная. Есть dash компоненты (django-plotly-dash), которые зависят от результата тяжелой обработки, и поскольку эта тяжелая обработка отправляется в фоновом режиме, django переходит непосредственно к dash компонентам, которые не имеют информации для отображения и поэтому возвращают ошибку. Поэтому я использовал Threading.join(), чтобы дождаться окончания тяжелой обработки, но это парализует весь сервер. Как я могу избежать блокировки сервера и позволить пользователю перемещаться между страницами, не блокируя весь сервер из-за тяжелой обработки?
Вот пример выполнения :
def read_csv(request):
heavy_treatment(some_args) # <-- this block the server and return a dash componant
return redirect(other_function_for_view) # <-- this loads the view containing the result of the heavy processing
Тогда я решил создать тему :
def read_csv(request):
t = threading.Thread(target=heavy_treatment, args=(some_args), daemon=False)
t.start() # <-- Task is sent to background
return redirect(other_function_for_view) # <-- Error : No result to display for dash componants
Error : Layout must be a dash component or a function that returns a dash component.
<div class={% plotly_class name='test_stackoverflow' %}>
{%plotly_app name="test_stackoverflow" ratio=1 %}
</div>
Решением может быть ожидание завершения потока, а затем отображение результатов :
def read_csv(request):
t = threading.Thread(target=heavy_treatment, args=(some_args), daemon=False)
t.start() # <-- Task is sent to background
t.join() # <-- wait for thread to finish <-- This block the server again
return redirect(other_function_for_view) # <-- redirect to html page and load dash components
Но при этом сервер блокируется, что не позволяет пользователям переходить с одной страницы на другую.
Я хотел бы запустить задачу в фоновом режиме, дождаться ее завершения и затем загрузить представление, не блокируя весь сервер.
Я хотел бы уточнить, что сельдерей не приспособлен для того, чем я занимаюсь, спасибо, что не предлагаете это решение
Вы можете попробовать использовать Django Asynchronous support. Она еще не закончена, но некоторые решения уже стабильны, и вы можете найти свое сейчас или в ближайшее время.