Cache, zonas e purge
Este doc cobre como a política de cache é resolvida no deploy, quais camadas
existem, como cf_zone controla o purge SSR, e quais flags por-env ajustam o
comportamento.
Para operar cache em incidente, use os playbooks de cache operations.
Config de cache no front-ops
Quatro arquivos em front-ops/config/cache/:
| Arquivo | O que é |
|---|---|
defaults.yml | Política do platform-cache (brand worker): recursos, TTL, SWR, stale-if-error, storage, snapshot KV, segmentos de purge pós-deploy, serviceApiPurge, infrastructure |
generation.yml | O token de cache generation da frota inteira (campo current) |
service-api-defaults.yml | Política do proxy front-service-api, no bloco rules: — mapeia prefixo de path do BFF → { ttl, methods, tags } |
monitor-routes.yml | Rotas que o purge-monitor.yml bate direto no BFF pra detectar drift de shape |
Camadas de cache que o deploy toca
| Camada | O que é | Como é invalidada no deploy |
|---|---|---|
| Cache generation | Prefixo de namespace comum a platform-cache, api-client e service-api | Rotaciona em TODO deploy — o valor efetivo é <generation.yml::current>-<BUILD_ID> |
| Platform cache | Cache API + snapshot KV por recurso (homeRows, allGames, …), gerido pelo @cactus-agents/platform-cache | POST <worker>/api/cache/purge?segments=… (step Purge platform cache after deploy). Pulado quando skip_post_deploy_purge: true |
| SSR cache (edge) | Doc HTML e .data cacheados na Cache API / KV do worker, TTLs por env | POST /zones/{id}/purge_cache (step Purge SSR cache (CF zone purge)) |
| service-api (proxy) | KV API_CACHE_KV + CF Cache API do front-service-api | Cascata a partir do /api/cache/purge do brand worker; mais um purge explícito antes e depois do deploy quando serviceApiPurge.enabled: true |
:::info A generation é hoje o mecanismo de invalidação mais forte
Porque o BUILD_ID é anexado ao token, cada deploy entra num namespace vazio
independentemente de qualquer purge ter funcionado. É por isso que envs atrás de
CF Access conseguem operar com skip_post_deploy_purge: true sem ficarem
permanentemente stale. Rotação manual da frota inteira:
playbook 11.
:::
Política de cache — precedência
A política do platform-cache é montada por merge, do mais geral para o mais específico:
config/cache/defaults.yml
< config/brands/<brand>/cache.yml (override de brand, opcional)
< config/brands/<brand>/environments/<env>/cache.yml (override de env, opcional)
defaults.ymldefine todos os recursos. É a base de todas as brands.cache.ymlda brand/env sobrescreve campos pontuais (deep-merge por recurso).
O service-api-defaults.yml tem a mesma cadeia, com os arquivos
service-api-cache.yml no lugar de cache.yml.
:::caution Sanity checks do merge
O pipeline falha o deploy se a política resolvida ficar null/vazia, ou se
algum recurso declarado em defaults.yml sumir após o merge. Isso evita subir um
Worker em modo BYPASS silencioso ou sem um segmento.
:::
KV provisioning
Se algum recurso usa storage.snapshot: kv, o pipeline provisiona o namespace KV
({worker_name}-cache por default, configurável em
defaults.yml::infrastructure.kvBindings) e injeta o binding
PLATFORM_CACHE_KV no wrangler.toml. Idempotente — reutiliza o namespace se já
existir.
Purge pós-deploy (platform cache)
Os segmentos purgados após o deploy vêm de postDeployPurge.segments
(defaults → brand → env, com replace total quando a brand/env define a chave).
Default atual (config/cache/defaults.yml):
postDeployPurge:
segments:
- homeRows
- casinoRows
- casinoLiveRows
- gamesBase
- topWins
- lastWins
- topGames
- brandConfig
- paymentProviders
O purge com ?segments=… apaga tanto o tier primário quanto o snapshot KV de
cada segmento. Além disso, o endpoint /api/cache/purge do Worker dispara um
purge em cascata no front-service-api, filtrado por originDomain.
:::info Desabilitar purge
Setar postDeployPurge.segments: [] pula o purge por segmentos (cai no
purgeAll() bare) — não recomendado, pois também pula a cascata no proxy.
:::
serviceApiPurge — purge explícito do proxy
serviceApiPurge:
enabled: false # default
Com enabled: true, o deploy dispara um purge só do cache do
front-service-api (via /api/cache/purge com { "only": "service-api" })
antes e depois do deploy. O purge normal por segmentos já cascateia pro
proxy; esta flag adiciona (a) o purge antes do deploy e (b) um purge explícito
só-service-api. Útil para brand que quer a camada BFF limpa em ambos os lados da
janela de deploy.
skip_post_deploy_purge
Setado no deploy.yml da env. Pula o purge por segmentos inteiro. Usado nos envs
atrás de Cloudflare Access, onde o endpoint /api/cache/purge é inalcançável
do runner do GitHub sem um Access service token. Quando ligado, o run mostra o
step Skip purge notice (when configured) e a invalidação fica por conta da
rotação de CACHE_GENERATION.
Cache SSR por env
Os TTLs do cache de resposta SSR são configurados por environment no
deploy.yml e injetados como [vars] no wrangler.toml:
ssr_cache:
html_ttl: 60 # default 60 — doc HTML
data_ttl: 60 # default 60 — respostas .data
kv_ttl: 180 # default 180 — snapshot KV do doc
data_browser_ttl: 0 # default 0 — TTL de browser p/ .data (0 = header omitido)
ssr_swr_enabled: false # SWR manual no edge (X-Cache: HIT-STALE)
shared_public_doc_for_auth: false # logado em rota pública recebe o doc anônimo cacheado
A dispersão real é grande: há env rodando os defaults de 60s e env rodando 30
dias de doc HTML (2592000). Consulte o deploy.yml da env antes de assumir
qualquer TTL.
:::caution ssr_swr_enabled e data_browser_ttl interagem
Há env com comentário explícito no config pedindo pra não setar
SSR_SWR_ENABLED porque isso anularia o TTL de browser configurado. Trate as duas
flags como acopladas.
:::
Cache warmer no brand worker
cache_warmer:
enabled: false # default
paths: ""
origin: "" # vazio = cai no ORIGIN_DOMAIN
Liga um Cron Trigger dentro do próprio brand worker que reaquece as rotas
listadas. Config por-env no front-ops (não no dashboard CF), injetada em
[vars].
:::caution Três coisas diferentes chamadas "warm"
cache_warmer.*— Cron Trigger dentro do brand worker (esta seção).- Step
Warm up cachedo deploy —curlnas rotas principais, roda sempre, uma vez por deploy. front-service-api-warmup— Worker separado, com caches pré-gerados por crons de GitHub Actions, e que cobre apenas 2 sites. Ver Serviços de infraestrutura.
Os três são mecanismos independentes. :::
SSR cache — cf_zone
O purge SSR chama POST /zones/{id}/purge_cache. Para achar {id} o workflow
consulta GET /zones?name=<zone> — que é strict-match (não faz fallback de
sufixo).
origin_domain/worker_urlapex (marca.com,7k.bet.br) resolvem naturalmente.origin_domain/worker_urlsubdomínio (cl.bet7k.com,stage-x.cactusgaming.tech) não resolvem por nome — a zona é o apex. Declarecf_zoneexplícito.
Quando declarar cf_zone explicitamente
Sempre que o domínio servido for subdomínio de uma zona diferente, ou quando
o origin_domain aponta para um backend que não é a zona CF onde o Worker é
servido.
origin_domain / worker_url | cf_zone | Motivo |
|---|---|---|
cl.bet7k.com | bet7k.com | zona apex |
pt.state77.com | state77.com | zona apex |
fi.7k.bet | 7k.bet | zona apex |
stage-7k-bet-br.cactusgaming.tech | cactusgaming.tech | zona apex do staging |
stage1.gli-cactus.com | c4ctus.com | origin é BFF backend; worker vive em outra zona |
Fallback quando cf_zone é ausente
O workflow deriva a zona de origin_domain usando uma shortlist de TLDs
compostos: bet.br, com.br, com.ar, com.mx, com.co, com.pe, co.uk,
co.id, co.ve. Domínios terminando num desses mantêm os últimos 3 labels;
os demais, os últimos 2.
Cobre apex e derivações simples subdomínio→apex. Fora disso (cross-zone, TLDs
fora da shortlist, hostnames atípicos), declare cf_zone.
Requisitos do token CF para o purge
O FRONT_{XX}_CF_API_TOKEN precisa de:
Zone > Zone > Read— para resolver o Zone IDZone > Cache Purge > Purge— para o purge SSR- Zone Resources incluindo cada
cf_zoneusado na conta
Falta de qualquer um → HTTP 401/403 no purge (warning, deploy ainda "verde",
mas cache stale). Ver debug em
Adicionar conta CF.
Monitoramento automático de drift
O purge-monitor.yml roda a cada 5 minutos. Para cada brand da matriz ele bate
nas rotas de config/cache/monitor-routes.yml direto no BFF
(bff_host, default api.bs2bet.com) com os headers cf-worker-key-proxy e
origin-domain, agrega as respostas em md5 e compara com o artifact do run
anterior. Em drift, dispara purge-all.yml daquela brand.
Precedência: brands.<slug>.routes substitui defaults.routes (replace
total, sem merge) — mesmo para bff_host. Omitir routes numa brand faz ela cair
inteiramente nos defaults, que é o caso típico.
Requer FRONT_{XX}_CF_WORKER_KEY_PROXY (com FRONT_{XX}_CF_WORKER_KEY como
fallback); sem nenhum dos dois o workflow erra.
Dev local
Em dev local a política de cache fica ausente por padrão → o engine entra em
bypass (chama as APIs direto), ideal para desenvolvimento. Para testar caching,
descomente PLATFORM_CACHE_POLICY_JSON no .dev.vars/.env. Para sincronizar a
política local com o front-ops:
pnpm check:dev-vars # verifica (faz parte do `pnpm quality`)
pnpm check:dev-vars --write # sincroniza
O script é scripts/sync-dev-vars-cache-policy.mjs, e o modo de verificação faz
parte do gate pnpm quality.