Вопрос проверяет понимание архитектуры асинхронного импорта, очередей задач и механизма отслеживания прогресса.
Асинхронный импорт строится вокруг очереди (RabbitMQ/Redis) и фоновых воркеров. После загрузки файл сохраняют, создают задачу импорта в БД и отправляют job в очередь. Воркеры обрабатывают файл в фоне, обновляют статус задачи и пишут прогресс. Пользователь получает taskId и периодически запрашивает статус. Это позволяет интерфейсу не блокироваться и продолжать работу.
Для асинхронной обработки необходимо разделить:
загрузку файла
постановку задачи
выполнение тяжёлой обработки
Backend:
принимает файл
сохраняет его в постоянное хранилище
создаёт запись в таблице imports:
id, filename, status='queued', progress=0
отправляет taskId клиенту
Пользователь получает мгновенный ответ и продолжает работать.
Worker-очередь получает job:
{ taskId: 123, filepath: "/uploads/x.xlsx" }
Очередь — RabbitMQ, Redis, SQS.
Воркер:
меняет статус → processing
открывает файл потоковым reader-ом
обрабатывает батчами
после каждого батча обновляет прогресс:
UPDATE imports SET progress = 37 WHERE id = 123;
после завершения → статус finished
при ошибке → errored
UI выполняет polling:
js
setInterval(() => {
fetch("/api/import/status?id=123")
.then(showProgress)
}, 2000)
Или WebSocket/SSE для push-уведомлений.
Когда прогресс = 100%, интерфейс уведомляет пользователя.
Чтобы UI мог показать ошибку.
Использовать streaming.
Выбирается по нагрузке.
Если воркер упал — очередь переназначит job другому воркеру.
Использовать status + idempotency.
Асинхронная обработка достигается комбинацией:
очереди задач
фоновых воркеров
потокового чтения файла
статуса прогресса
периодического опроса интерфейса
Это позволяет пользователю продолжать работу, пока импорт выполняется в фоне.