Pular para o conteúdo principal

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/:

ArquivoO que é
defaults.ymlPolítica do platform-cache (brand worker): recursos, TTL, SWR, stale-if-error, storage, snapshot KV, segmentos de purge pós-deploy, serviceApiPurge, infrastructure
generation.ymlO token de cache generation da frota inteira (campo current)
service-api-defaults.ymlPolítica do proxy front-service-api, no bloco rules: — mapeia prefixo de path do BFF → { ttl, methods, tags }
monitor-routes.ymlRotas que o purge-monitor.yml bate direto no BFF pra detectar drift de shape

Camadas de cache que o deploy toca

CamadaO que éComo é invalidada no deploy
Cache generationPrefixo de namespace comum a platform-cache, api-client e service-apiRotaciona em TODO deploy — o valor efetivo é <generation.yml::current>-<BUILD_ID>
Platform cacheCache API + snapshot KV por recurso (homeRows, allGames, …), gerido pelo @cactus-agents/platform-cachePOST <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 envPOST /zones/{id}/purge_cache (step Purge SSR cache (CF zone purge))
service-api (proxy)KV API_CACHE_KV + CF Cache API do front-service-apiCascata 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.yml define todos os recursos. É a base de todas as brands.
  • cache.yml da 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 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"

  1. cache_warmer.* — Cron Trigger dentro do brand worker (esta seção).
  2. Step Warm up cache do deploy — curl nas rotas principais, roda sempre, uma vez por deploy.
  3. 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_url apex (marca.com, 7k.bet.br) resolvem naturalmente.
  • origin_domain/worker_url subdomínio (cl.bet7k.com, stage-x.cactusgaming.tech) não resolvem por nome — a zona é o apex. Declare cf_zone explí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_urlcf_zoneMotivo
cl.bet7k.combet7k.comzona apex
pt.state77.comstate77.comzona apex
fi.7k.bet7k.betzona apex
stage-7k-bet-br.cactusgaming.techcactusgaming.techzona apex do staging
stage1.gli-cactus.comc4ctus.comorigin é 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 ID
  • Zone > Cache Purge > Purge — para o purge SSR
  • Zone Resources incluindo cada cf_zone usado 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.