Чому дублі — це не рідкість, а системний ризик
При заливці на десятки кабінетів збій посередині процесу — статистично очікувана подія: мережа моргнула, Meta повернула тимчасову помилку, процес впав. Наївна реалізація «натиснув кнопку — запусти все заново» в цій ситуації створює дублі саме там, де все вже вийшло, і це дізнається не одразу, а коли в Ads Manager раптово подвійний бюджет на той самий офер.
Звідки беруться дублі технічно
Проблема — не сам збій, а відсутність пам'яті про те, що вже зроблено. Якщо стан процесу живе тільки в оперативній пам'яті запущеного скрипта, при падінні він втрачається повністю: система не знає, на якому кабінеті вона зупинилася, і при повторному запуску починає з кампанії №1 знову — навіть якщо кампанії №1–30 з 50 вже реально створені на Facebook.
Рішення — журнал, ключ запуску і звірка з Facebook
Перше — журнал у базі даних, не в пам'яті: результат кожного кроку (створено кампанію X на кабінеті Y — успіх/помилка) записується одразу після факту, а не наприкінці всього процесу. При збої і «Перезапустити» система читає журнал і продовжує з місця зупинки.
Одного журналу замало. Найтонший випадок — неясний результат: запит на створення пішов у Facebook, а відповідь не прийшла (обрив мережі, таймаут). Об'єкт міг створитися, а міг і ні — журнал цього не знає. Тому в кожного кроку є ключ запуску, а перед повтором система звіряється з Facebook: чи є вже об'єкт із цим ключем. Є — бере його, новий не створює. Не вдалося однозначно зрозуміти — не створює «про всяк випадок» другий, а позначає кабінет: перевір в Ads Manager. Краще одне питання людині, ніж задвоєний бюджет.
Що це означає на практиці для користувача
- Кнопку «Перезапустити» безпечно натискати кілька разів поспіль — повторний виклик не створює нових об'єктів там, де вони вже є.
- Якщо результат кроку неясний, AdFleet не вгадує: кабінет позначено «перевір в Ads Manager», і рішення за вами.
- Журнал запуску показує статус по кожному кабінету окремо (успіх/помилка), а не загальне «готово/не готово» на весь запуск — видно точно, що пішло не так і де.
- Скасований запуск не відкочує вже створене на Facebook — скасування просто не йде далі, вже створене залишається як є (це свідоме рішення: відкат реальних об'єктів реклами — окрема і більш ризикована операція, ніж просто зупинка).