Почему дубли — это не редкость, а системный риск
При заливке на десятки кабинетов сбой на середине процесса — статистически ожидаемое событие: сеть моргнула, Meta вернула временную ошибку, процесс упал. Наивная реализация «нажал кнопку — запусти всё заново» в этой ситуации создаёт дубли ровно там, где всё уже получилось, и это узнаётся не сразу, а когда в Ads Manager внезапно двойной бюджет на один и тот же оффер.
Откуда берутся дубли технически
Проблема — не сам сбой, а отсутствие памяти о том, что уже сделано. Если состояние процесса живёт только в оперативной памяти запущенного скрипта, при падении оно теряется полностью: система не знает, на каком кабинете она остановилась, и при повторном запуске начинает с кампании №1 снова — даже если кампании №1–30 из 50 уже реально созданы на Facebook.
Решение — журнал, ключ запуска и сверка с Facebook
Первое — журнал в базе данных, не в памяти: результат каждого шага (создана кампания X на кабинете Y — успех/ошибка) записывается сразу после факта, а не в конце всего процесса. При сбое и «Перезапустить» система читает журнал и продолжает с места остановки.
Одного журнала мало. Самый тонкий случай — неясный исход: запрос на создание ушёл в Facebook, а ответ не пришёл (обрыв сети, таймаут). Объект мог создаться, а мог и нет — журнал этого не знает. Поэтому у каждого шага есть ключ запуска, а перед повтором система сверяется с Facebook: есть ли уже объект с этим ключом. Есть — берёт его, новый не создаёт. Не удалось однозначно понять — не создаёт «на всякий случай» второй, а помечает кабинет: проверь в Ads Manager. Лучше один вопрос человеку, чем задвоенный бюджет.
Что это значит на практике для пользователя
- Кнопка «Перезапустить» безопасна нажимать несколько раз подряд — повторный вызов не создаёт новых объектов там, где они уже есть.
- Если исход шага неясен, AdFleet не угадывает: кабинет помечен «проверь в Ads Manager», и решение за вами.
- Журнал запуска показывает статус по каждому кабинету отдельно (успех/ошибка), а не общий «готово/не готово» на весь запуск — видно точно, что пошло не так и где.
- Отменённый запуск не откатывает уже созданное на Facebook — отмена просто не идёт дальше, что уже создано, остаётся как есть (это осознанное решение: откат реальных объектов рекламы — отдельная и более рискованная операция, чем просто остановка).