ADS: VAST has implicit dependency on popunder cooldown

DEPLOY: document custom CDN stale-cache gotcha + recovery

Findings from 8148 production debug session 2026-05-02:

1. VAST gotcha — _decide() mode логіка:
   mode = popActive ? (vastActive || skipPattern ? "none" : "vast") : "pop"
   Тобто VAST loadable ТІЛЬКИ після того як popunder уже спрацював і
   _popRr cooldown set. На свіжій сесії: mode завжди "pop" → VAST SDK
   never loaded → користувач думає "VAST зламаний". Force test через
   ?clearAds=1 → pop fires → refresh → mode=vast.

2. CDN stale-cache — custom CDN кешує `?v=<hex-like>` URLs з
   s-maxage=31536000 (1 рік). Race у deploy: layout.etlua з новим ?v=
   може hit CDN раніше ніж static file → CDN кешує OLD bundle під
   NEW ?v= ключем → застрягає назавжди. Workaround: bump source md5,
   rebuild, новий ?v= ключ.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
goboss
2026-05-02 21:51:32 +00:00
parent a2d637c483
commit d59393a608
2 changed files with 42 additions and 4 deletions

View File

@@ -175,10 +175,23 @@ tb.load_frame_baner_v2("//surstrom.com/api/spots/72437?p=1","#tb0",{...},{...});
### Mode decision (`AdCore._decide`)
- `popActive = true && vastActive = true``none` (поки активна `recoverFromNone`)
- `popActive = false``pop` (priority)
- `popActive = true && vastActive = false``vast`
- AND `vastPolicy "show-1-skip-1"` skip pattern на половину VAST imps
```
mode = popActive ? (vastActive || skipPattern ? "none" : "vast") : "pop"
```
| popunder | vast | mode |
|----------|------|------|
| available (cooldown OFF) | — | **pop** (priority) |
| у cooldown (recent fire) | available + не skip-pattern | **vast** |
| у cooldown | у cooldown OR skip-pattern | none |
**Implicit dependency:** VAST показується **тільки після того як popunder уже спрацював** і поставив cooldown. На свіжій сесії (нема `_popRr` у localStorage / cookies) → mode завжди "pop", VAST SDK навіть не завантажується.
⚠️ Це **gotcha при тестуванні**: якщо щойно фікснули popunder spot — VAST не з'явиться поки popunder не спрацює хоча б раз. Юзер має думати що "VAST зламаний", а він просто заблокований mode logic.
**Force VAST testing**: `?clearAds=1` URL param очищає `_popRr/_vastRr/_vastPatternIdx/_pw/asgsl/_pjsLog` — фрешний state. Тоді: page load → pop fires → cooldown set → refresh → mode=vast → VAST SDK loaded.
`vastPolicy "show-1-skip-1"` додатково: idx=0 → SHOW, idx=1 → SKIP (incremented per VAST impression). На свіжій сесії idx=0 → перша VAST показується, друга skip-неться.
### Policy choice

View File

@@ -66,6 +66,31 @@ Trigger: попросити (чат / задача).
- **При оновленні prod** для Cloudflare-сайтів: треба **purge cache** + враховувати у логіці що зміни не миттєві (cache TTL до purge)
- Cache-bust через `?v=<md5>` у `layout.etlua` працює для обох (custom + CF)
### ⚠️ Stale-cache gotcha (custom CDN, 8148 confirmed 2026-05-02)
Custom CDN serve-ить різні `cache-control` залежно від виду query string:
| Pattern URL | s-maxage | Поведінка |
|-------------|----------|-----------|
| `?v=<hex-like-7-chars>` (md5 prefix) | **31536000 (1 рік)** | "Content-addressed asset" — immutable, edge cache aggressive |
| `?v=<short>` (число, ZZZZ etc.) | 10 sec | Швидко refresh-иться |
| (no query) | ~ | Звичайний cache |
**Race condition при deploy:**
1. Template (layout.etlua) deploy-иться з новим `?v=<new_md5>` reference
2. До того як static (`ad-bundle.min.js`) сам file deploy-иться — браузер/crawler hit-ить `<host>/ad-bundle.min.js?v=<new_md5>`
3. CDN cache-miss → origin ще має OLD bundle → CDN кешує OLD під новим `?v=` ключем
4. Static deploy-иться з NEW bundle, але **CDN cache stuck на 1 рік** з OLD content
**Симптом:** `curl <host>/ad-bundle.min.js` → NEW. `curl <host>/ad-bundle.min.js?v=<deployed_md5>` → OLD. Live site поломаний.
**Рішення:**
- Bump bundle md5 (тривіальна зміна у source — додаткова line, build stamp): `git-save-all.sh` rebuilds → новий md5 → новий ?v= → нова cache entry → fresh
- Або **purge CDN cache** (через адмін / hostiserver)
- Краще довгостроково: змінити cache-bust scheme у `git-save-all.sh` щоб включав timestamp (`?v=<md5>-<unix>`) → завжди унікально
Перевірка чи це сталося: `curl -sI <host>/<file>?v=<md5> | grep s-maxage` — якщо `31536000`, кеш заблокувався на рік.
## git-save-all.sh — git-snapshot для backup_<port>/
`~/git-save-all.sh "msg"` ітерує `/home/w4/backup_*/`: