Как запускать потоки и ждать их окончания, не блокируя сервер 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. Она еще не закончена, но некоторые решения уже стабильны, и вы можете найти свое сейчас или в ближайшее время.

Вернуться на верх