Техническое руководство
Отмена video API задачи: состояния, сверка и безопасная выдача результата
Отмена video API задачи — это не кнопка, которая гарантированно мгновенно остановит внешнюю обработку. Между запросом cancel, callback и готовым результатом возможны гонки, задержки и разные правила текущего контракта. Поэтому приложение сначала меняет собственное состояние, проверяет владельца задачи и сохраняет намерение отмены, а затем выполняет только подтверждённый сценарий RussiaAPI. Такой подход не обещает отмену конкретной модели, но не выдаёт результат ошибочно и не создаёт дубль.
RUSSIAAPI_API_KEY на сервере; не передавайте внешние ключи, cookie, пароли, коды подтверждения или лишние персональные данные.Отделите просьбу пользователя от внешней отмены
Кнопка «Отменить» должна обращаться к вашему backend, а не к внешнему URL из браузера. Backend находит внутреннюю операцию, проверяет tenant и её текущее состояние. Если задача уже готова, пользователь получает результат по обычной авторизации или честное объяснение, что отмена больше не применима. Если операция выполняется, сервер записывает cancel_requested и возвращает наблюдаемый статус.
Внешний cancel вызывайте только если он указан для выбранного типа задачи в актуальной документации. Не угадывайте endpoint, заголовок или статус по примеру другой видео-модели. Когда специальной отмены нет, ваша политика может запретить выдачу ещё не полученного результата, но не должна заявлять, что вычисление у поставщика остановлено. Базовые состояния асинхронного потока описаны в руководстве по video-задачам.
Постройте монотонную state machine
Полезные внутренние состояния: submitted, processing, cancel_requested, cancelled, ready, failed и checking. Разрешите только явные переходы. Например, cancel_requested может стать cancelled после подтверждённой сверки, но callback ready, пришедший раньше записи, требует отдельного решения политики: безопасно ли оставить результат недоступным, предупредить владельца или проверить фактический статус. Нельзя позволить запоздалому processing вернуть cancelled назад.
Храните внутренний task ID, provider reference при наличии, владельца, время запроса отмены и безопасную причину. Не храните временный URL результата или полный payload в общем логе. Уникальная запись операции защищает от двух кликов и параллельных worker. Если пользователь повторил cancel, верните текущий статус, а не отправляйте внешнюю команду второй раз.
Разрешите гонку cancel и callback
Представьте два порядка: callback ready пришёл за секунду до cancel или спустя секунду после него. В обоих случаях HMAC-подпись callback, если она документирована, и idempotency доставки проверяются отдельно от бизнес-правила отмены. Достоверный callback не означает, что результат следует немедленно показать: backend сопоставляет task ID, tenant и допустимый переход состояния.
Если состояние неясно после timeout, пометьте его checking и выполните ограниченную сверку по разрешённому контракту. Не создавайте новую задачу и не утверждайте «отменено» без подтверждения вашей политики. Проверка подписи снижает риск поддельного события, а журнал доставок предотвращает повторный эффект; эти механизмы разобраны в проверке webhook-подписи.
Серверный обработчик отмены
Ниже Node.js 18+ пример фиксирует намерение отмены до сетевого действия и использует транзакцию для повторного клика. Функция cancelIfDocumented — ваш контрактный адаптер: она должна вызывать только проверенный путь для разрешённого типа задачи либо возвращать «не поддерживается». Код не раскрывает секреты и не является обещанием, что любая модель RussiaAPI поддерживает отмену.
export async function requestCancel({ tenantId, taskId }) {
return db.transaction(async (tx) => {
const task = await tx.findTaskForTenant(tenantId, taskId);
if (!task) return { status: 'not_found' };
if (['cancelled', 'failed', 'ready'].includes(task.status)) return { status: task.status };
if (task.status === 'cancel_requested') return { status: 'checking' };
await tx.transition(task.id, 'cancel_requested');
await tx.insertOutboxOnce({ key: `cancel:${task.id}`, kind: 'cancel_if_documented' });
return { status: 'cancel_requested' };
});
}
export async function cancelIfDocumented(task) {
if (!task.supportsDocumentedCancel) return { status: 'checking' };
// Call only the route confirmed for this task type; key stays in server env.
return { status: 'sent_for_confirmation' };
}В production worker, который делает внешнюю отмену, должен иметь ограниченный retry и безопасный журнал. Если он получил timeout, не переключайте операцию в cancelled автоматически. Сначала прочитайте внутреннюю запись и выполните сверку. Такой порядок также не позволяет пользователю отменить задачу другого tenant по угадываемому ID.
Не путайте отмену и удаление результата
Отмена будущей выдачи, удаление уже сохранённого результата и прекращение внешней обработки — разные действия. Для каждого определите владельца, срок, журнал и способ подтверждения. Если вы храните готовое видео, политика доступа и удаления относится к вашему хранилищу; URL может иметь отдельный срок и правила. Не обещайте постоянное хранение или мгновенное удаление без фактической реализации и документации.
Пользователю полезнее увидеть точный внутренний статус и дальнейшее действие, чем абстрактное «успешно». При необходимости предложите безопасно удалить результат из собственного проекта или обратиться к оператору. Вопросы доступа и срока результата раскрыты в статье о URL video API.
Проверьте отмену до запуска
Документированный контракт важнее удачного единичного запроса. Перед изменением зафиксируйте версию клиента, базовый URL, выбранный model ID, ожидаемый код ответа, обязательные поля и то, что приложение считает безопасной ошибкой. Не подменяйте проверку предположениями по чужому примеру: каталог, права, параметры и поведение конкретной модели могут измениться.
Тестовый контур должен использовать обезличенный вход, отдельный собственный ключ и ограниченный бюджет. Он не должен записывать Authorization, полный prompt, ответ с персональными данными или временную ссылку на результат. Это делает проверку воспроизводимой и одновременно уменьшает риск утечки в CI, журнале или тикете.
Наблюдаемость полезна, когда по ней можно принять решение. Храните внутренний request ID, статус, длительность, тип операции, версию маршрута и безопасный итог проверки. Связывайте их с проектом только после серверной авторизации. Не делайте метрику или очередь общим каналом для данных разных tenant.
Ошибки 400, 401, 403, 429 и 5xx имеют разные действия. Не запускайте бесконечный retry и не меняйте модель молча: timeout может означать неопределённость, а повторная асинхронная задача способна создать дубль. Для проверки сначала прочитайте своё внутреннее состояние и текущую документацию, затем выполните ограниченный шаг, разрешённый вашей политикой.
До релиза выполните короткий негативный набор: отсутствующая переменная окружения, неподходящий model ID, лишнее поле, недоступный маршрут, timeout и повтор одного запроса. Проверяйте не только HTTP-статус, но и то, что клиент не вывел секрет, не смешал владельцев и не сообщил пользователю неподтверждённую готовность результата.
Эта инженерная практика не обходит лимиты, правила поставщика, применимое право или ограничения платформ. Если контракт, цена, доступность или политика обработки данных изменились, остановите рискованный rollout, обновите тест и подтвердите сценарий в актуальном каталоге RussiaAPI и своих договорных материалах.
Проверьте сценарий в RussiaAPI
Создайте собственный тестовый ключ в консоли, сверьте текущий каталог моделей и выполните обезличенный server-side smoke test. Расширяйте нагрузку и доступ только после измеримой проверки.
FAQ
Гарантирует ли cancel остановку генерации?
Нет. Возможность и момент отмены зависят от текущего контракта конкретной задачи. Ваше приложение должно честно показывать внутреннее состояние и подтверждать внешнюю отмену только после разрешённой сверки.
Что делать, если ready callback пришёл после cancel?
Проверить подпись по текущему контракту, сопоставить внутреннюю задачу и применить заранее определённый допустимый переход. Не выдавайте результат автоматически только из-за события.
Можно ли отменить задачу из браузера по task ID?
Нет. Браузер должен обратиться к вашему авторизованному backend. Он проверяет владельца, tenant, состояние и применяет серверную политику без раскрытия внешних ключей.