Какие статусы могут быть у задачи генерации картинки кроме 'in queue'
Что проверяют
Умеете ли вы проектировать долгую асинхронную операцию как конечный автомат: какие состояния, какие переходы разрешены, что конечно, а что может зависнуть. Следом обычно спрашивают, что будет, если воркер умер посреди генерации, и как клиент узнаёт о готовности.
Как отвечать
Предложите набор статусов и покажите переходы:
queued: задача принята и ждёт свободного воркера с GPU;running: воркер взял задачу. Полезно хранить прогресс (шаг диффузии) и время последнего heartbeat;succeeded: картинка лежит в объектном хранилище, в задаче ссылка на результат;failed: ошибка с кодом причины: нехватка памяти GPU, невалидные параметры, таймаут;cancelled: отменено пользователем. Для уже запущенной задачи удобно промежуточноеcancelling, пока воркер не остановится;rejected: промпт или результат не прошли модерацию. Это не техническая ошибка, и показывать её надо иначе;retrying: временный сбой, задача вернётся в очередь, счётчик попыток растёт;expired: задача слишком долго ждала в очереди или результат удалён по сроку хранения.
Из конечных состояний (succeeded, failed, cancelled, rejected, expired) переходов нет. Переход делайте атомарным: UPDATE tasks SET status = 'running' WHERE id = %s AND status = 'queued', тогда два воркера не возьмут одну задачу. Зависшие running без heartbeat дольше таймаута отдельный процесс переводит в retrying или failed.
На Celery вспомните встроенные состояния: PENDING, STARTED (только при task_track_started), RETRY, SUCCESS, FAILURE, REVOKED. Клиенту статус отдают поллингом, вебхуком или через SSE.
Где спотыкаются
Не предусматривают зависание: воркер упал, задача навсегда осталась в running, пользователь смотрит на бесконечный спиннер.
Доверяют PENDING в Celery. Это состояние возвращается и для неизвестного id, поэтому настоящий статус лучше хранить в своей таблице.
Смешивают отказ модерации с технической ошибкой. Пользователь видит «что-то пошло не так», жмёт повтор, и задача снова уходит на дорогой GPU.