<!-- Canonical URL: https://ask.atlascloud.ai/ru/avoid-duplicate-video-jobs-api-timeout -->

# Как избежать повторных видеозаданий при тайм-ауте API-запроса?

> Предотвращайте дубли, назначая каждому задуманному результату стабильный ключ операции, сохраняя запрос до отправки, используя документированную идемпотентность провайдера и сверяя неоднозначные тайм-ауты до повтора. Тайм-аут означает неизвестный исход, а не отказ провайдера.

<!-- Canonical URL: https://ask.atlascloud.ai/avoid-duplicate-video-jobs-api-timeout -->

# Как избежать повторных видеозаданий при тайм-ауте API-запроса?

Тайм-аут отправки создает неоднозначный исход. Запрос мог не дойти до сервиса, дойти и быть отклоненным либо создать удаленное видеозадание, ответ на которое не вернулся клиенту. Немедленный повтор способен превратить один задуманный ролик в две оплачиваемые генерации.

Решение — идемпотентный слой операций вокруг видео-API. Сначала создайте и сохраните задуманную операцию, назначьте ей стабильный ключ, записывайте каждую попытку и используйте документированную идемпотентность или поиск провайдера. Если удаленный исход нельзя доказать, переводите операцию в явное неизвестное состояние, а не объявляйте неудачной.

## Определите одно намеренное действие

Ключ идемпотентности должен определять то, что пользователь хочет создать, а не отдельную HTTP-попытку. Если каждый повтор получает новый ключ, провайдер не распознает дубль.

Операция каталога может включать:

* ID товара;
* версию креативного шаблона;
* отпечаток исходных медиа;
* версию промпта;
* локаль;
* соотношение сторон;
* название варианта.

Создайте каноническое представление со стабильным порядком и нормализованными значениями, затем вычислите хеш. Храните читаемые измерения рядом. Намеренно новая независимая генерация должна получить новую операцию или вариант, даже при одинаковом промпте.

Не создавайте случайный UUID внутри цикла повторов. Сформируйте ключ до первого запроса и переиспользуйте его до терминального состояния действия.

## Сохраняйте до отправки

Локальная база должна знать об операции до начала сетевого вызова. Это принцип предварительной записи для побочных эффектов API.

| Поле | Назначение |
|---|---|
| Ключ операции | Предотвращает повторное локальное намерение |
| Хеш запроса | Доказывает отправленные параметры |
| Состояние | Различает подготовлено, отправлено, неизвестно и завершено |
| Число попыток | Ограничивает повторы |
| Провайдер и модель | Нужны для маршрута и сверки |
| Удаленный ID | Позволяет опрашивать без повторной отправки |
| Последняя ошибка | Сохраняет контекст диагностики |
| Контрольная сумма | Выявляет повторные или измененные ресурсы |

Наложите уникальность на ключ. Два воркера, создающие одну операцию, должны сойтись на одной записи. До отправки заберите ее атомарным обновлением или арендой.

## Используйте идемпотентность провайдера только по документации

Некоторые API принимают ключ или токен и при повторе возвращают результат первого принятого запроса. Это лучший путь, когда документация ясно описывает эндпоинт, срок хранения, сравнение параметров и ошибки.

Проверьте:

* поддерживает ли ключ видеогенерация;
* как долго он хранится;
* отклоняется ли тот же ключ с другими параметрами;
* возвращают ли повторы исходный удаленный ID.

Не предполагайте, что заголовок для платежей или синхронного текста действует для асинхронного видео. OpenAI-совместимая форма запроса не делает специфичное создание заданий автоматически идемпотентным.

## Считайте тайм-аут неизвестным исходом

| Состояние | Доказательство | Следующее действие |
|---|---|---|
| `prepared` | Локальная запись есть, отправка не началась | Отправить |
| `sending` | Воркер начал запрос | Ждать ответа или тайм-аута |
| `accepted` | Получен удаленный ID | Опросить |
| `unknown` | Тайм-аут без подтверждения | Сверить |
| `failed` | Провайдер явно отказал или завершил ошибкой | Применить политику ошибки |
| `complete` | Результат сохранен постоянно | Вернуть существующий результат |

Различие `unknown` и `failed` принципиально. Сетевая ошибка говорит о соединении клиента, но не обязательно о работе провайдера.

Если API позволяет метаданные или клиентскую ссылку, прикрепите локальный ключ, чтобы позднее искать стабильное значение.

## Сверяйте до повтора

Воркер сверки исследует неизвестную операцию:

1. Проверяет, сохранила ли попытка удаленный ID до сбоя.
2. Запрашивает провайдера по ключу или клиентской ссылке.
3. Ищет в ограниченном списке по времени, модели и отпечатку.
4. Проверяет webhook-события, пришедшие после тайм-аута.
5. Сопоставляет события использования или оплаты, если они доступны.
6. Повторяет лишь при доказанном отсутствии задания или гарантированной идемпотентности.

Совпадение только по времени и промпту может быть ложным. Используйте несколько признаков и отправляйте неуверенные случаи на проверку. Если нет поиска и гарантий, политика может требовать ожидания, принятия риска дубля или решения человека по стоимости и сроку.

## Разделяйте транспортные и творческие повторы

HTTP-библиотеки нередко автоматически повторяют сетевые ошибки. Это полезно для чтения, но опасно для POST с побочным эффектом. Отключите общие повторы, если операция не защищена стабильным ключом и документированным поведением.

Используйте два счетчика:

* транспортные попытки отправки той же защищенной операции;
* генерационные попытки создания замены после финального сбоя или отклонения качества.

Транспортный повтор должен сходиться в одном удаленном задании. Генерационный — новая оплачиваемая творческая попытка со своей идентичностью, связанная с исходным производственным заданием.

## Защищайте параллельных воркеров арендой

Дубли появляются не только из-за тайм-аутов. Два воркера могут взять один элемент, а медленный — продолжить после истечения блокировки.

Забирайте работу атомарной арендой с владельцем, временем начала и сроком. До отправки воркер проверяет владение и отсутствие уже принятого удаленного задания. Записывайте удаленный ID транзакцией или условным обновлением, которое не пройдет, если другой воркер продвинул операцию.

При риске записи устаревшим воркером используйте fencing-токены. Каждая аренда повышает версию, а база принимает изменения только от последней.

## Сводите webhooks и опрос к одному результату

Видео асинхронно, поэтому webhook и опрос могут сообщить один переход. Их обработчики тоже должны быть идемпотентными.

Дедуплицируйте события по ID и обновляйте состояние условно: `processing` не должен откатывать `complete`. Повторное скачивание пишет во временный детерминированный ключ, проверяет сумму и сходится в одном объекте.

```text
получить завершение
найти операцию по удаленному ID
скопировать результат по детерминированному ключу
проверить медиа и сумму
записать постоянный URI
пометить завершенным, если еще не завершено
```

После сбоя следующий обработчик продолжает без новой генерации.

## Сохраняйте доказательства для аудита дублей

Для попытки храните время отправки, тип тайм-аута, хеш запроса, ключ идемпотентности, заголовки ответа, удаленный ID и решение о повторе. Редактируйте секреты.

| Показатель | Что он показывает |
|---|---|
| Неизвестные отправки | Неоднозначность сети или провайдера |
| Сверено без повтора | Успешно предотвращенные дубли |
| Защищенные повторы | Поведение идемпотентности при сбоях |
| Подозрительные дубли | Оставшийся финансовый риск |
| Повторная контрольная сумма | Тот же или повторный результат |
| Время в unknown | Скорость восстановления |

Сигнализируйте о росте неизвестных исходов до увеличения лимитов: проблема сети и агрессивные повторы быстро умножают расходы.

## Скрывайте различия провайдера за адаптером

Мультимодельное приложение должно иметь один внутренний интерфейс отправки и флаги возможностей. Адаптер отвечает за схему, идемпотентность, поиск, статусы и извлечение результата.

[Atlas Cloud](https://www.atlascloud.ai/?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=avoid-duplicate-video-jobs-api-timeout) может сократить интеграционную работу для текстовых, графических и видеомоделей на OpenAI-совместимой платформе. Но проверяйте текущее поведение конкретной модели и эндпоинта: совместимость не является универсальной гарантией идемпотентности асинхронных заданий.

Возвращайте нормализованный исход: принято с ID, явно отклонено или неизвестно. Не превращайте транспортные исключения в ошибки провайдера.

## Намеренно тестируйте неоднозначные случаи

Успешный путь не доказывает защиту от дублей. В тестовой среде создавайте сбои до отправки, после выхода байтов, после приема провайдером, после ответа до записи в базу и при webhook-доставке.

При поддержке идемпотентности одна операция должна создавать не более одного удаленного задания. Без нее операция обязана перейти в `unknown`, остановить автоматическую отправку и показать доказательства для выбранной политики.

Тестируйте параллельных воркеров, истекшие аренды, поздние и повторные webhooks, перезапуски и старый ключ с новыми параметрами. Это дешевле, чем находить дубли в счете.

## Итог

Давайте каждому задуманному результату один постоянный ключ и отделяйте операцию от HTTP-попыток. Сохраняйте намерение до отправки, используйте документированную идемпотентность и считайте тайм-аут неизвестным исходом, требующим сверки. Аренды, условные переходы, идемпотентное завершение и постоянные журналы превращают повторы в управляемое восстановление, а не случайную двойную покупку.

## FAQ

### Означает ли HTTP-тайм-аут, что видео-API не создал задание?

Нет. Провайдер мог принять запрос и создать задание, хотя клиент не получил ответ. Считайте исход неизвестным до сверки.

### Что должен представлять ключ идемпотентности?

Одно намеренное действие: конкретные товар, версия шаблона, локаль, соотношение сторон и вариант. Переиспользуйте его для повторов этой операции, но создавайте новый для действительно нового результата.

### Может ли уникальное ограничение базы предотвратить все дубли?

Оно предотвращает повторные локальные операции, но само по себе не мешает провайдеру принять два запроса. Сочетайте его с идемпотентностью провайдера или сверкой.

### Следует ли автоматически повторять каждый тайм-аут?

Нет. Это безопасно лишь когда запрос идемпотентен или исход у провайдера можно определить. Иначе переведите задание в неизвестное состояние и сначала сверьте.

### Как долго хранить записи идемпотентности?

Не меньше окна повторов, периода поиска у провайдера, срока спора по счету и потребности аудита. Учитывайте документированное поведение и бизнес-риск.

### Гарантирует ли OpenAI-совместимый API одинаковую идемпотентность всех видеомоделей?

Нет. Совместимость унифицирует транспорт, но асинхронное создание заданий и идемпотентность могут зависеть от модели и провайдера. Проверяйте актуальную документацию эндпоинта.
