Pular para o conteúdo principal

Caching

O template implementa caching em multiplas camadas para otimizar performance no Cloudflare Workers.

:::info Nova engine A partir da versao atual, dados de API (brand, jogos, stats) sao gerenciados pelo @cactus-agents/platform-cache, substituindo o antigo ServerCache manual. A politica de cache e configurada no front-ops e injetada como PLATFORM_CACHE_POLICY_JSON em deploy-time. Veja SDK > platform-cache para detalhes. :::

Camadas de cache

Requisicao do usuario
|
v
[1] Worker Middleware — SSR response cache (edge, 60s)
|
v
[2] platform-cache engine — dados de API (memory + CF Cache API + KV)
| - brandConfig: TTL 3600s
| - homeRows: TTL 300s
| - gamesBase: TTL 300s
| - gameStats/gameDetail: TTL 300s
v
Backend API

Camada 1 — SSR Response Cache (Worker Middleware)

Cacheia respostas HTML de SSR no edge da Cloudflare para visitantes anonimos.

Regras

CondicaoComportamento
Metodo != GETBYPASS
Path comeca com /api/ ou /proxy/BYPASS
Cookie jwt_token presenteBYPASS (usuario autenticado)
DemaisCACHE (HTML)

Politica

  • Fresh: s-maxage=60 (1 minuto)
  • Stale: stale-while-revalidate=300 (5 minutos)
  • Header X-Cache: HIT, MISS ou BYPASS

Smartico Proxy

O middleware tambem proxeia /proxy/smartico.js:

  • Origem: https://libs.s.cactusgaming.net/scactus.js
  • Cache: s-maxage=3600, stale-while-revalidate=86400 (1h fresh, 24h stale)
  • CORS: Access-Control-Allow-Origin: *

Em dev, o plugin vite-plugins/dev-proxy-mirror.ts espelha a rota /proxy/smartico.js no Vite dev middleware — o worker não executa em dev. Manter o upstream em sincronia com workers/middleware.ts.

Brands devem apontar gamificationConfig.smartico.libraryUrl pra /proxy/smartico.js (em vez de direto pra libs.s.cactusgaming.net) pra manter a URL same-origin no HTML e aproveitar o cache edge.

Camada 2 — platform-cache engine

O @cactus-agents/platform-cache substitui o antigo ServerCache manual. E criado no loader SSR com base na PLATFORM_CACHE_POLICY_JSON injetada pelo front-ops:

import { createCacheEngine, parseCachePolicy, CacheApiStore, NoopSnapshotStore } from "@cactus-agents/platform-cache";

const engine = createCacheEngine({
policy: parseCachePolicy(env.PLATFORM_CACHE_POLICY_JSON),
primaryStore: new CacheApiStore(),
snapshotStore: env.PLATFORM_CACHE_KV
? new KvSnapshotStore(env.PLATFORM_CACHE_KV)
: new NoopSnapshotStore(),
domain: env.ORIGIN_DOMAIN,
});

Quando PLATFORM_CACHE_POLICY_JSON esta ausente (dev local), o engine opera em modo bypass — todas as requisicoes vao direto para a API, sem cache.

ServerCache (legado — mantido para referencia)

O ServerCache manual ainda existe nos arquivos do template para o SSR response cache e casos de uso legacy nao migrados.

Classe base para cache server-side de 2 niveis:

Niveis

  1. In-memory (Map no isolate do Worker) — hit instantaneo, compartilhado dentro do mesmo isolate
  2. CF Cache API (caches.default) — compartilhado entre isolates, persiste alem do lifecycle do Worker

Lookup

get(key)
|
├── [memory] fresh → retorna
├── [memory] stale → retorna (marcado como stale)
├── [CF Cache] hit → retorna + popula memory
└── miss → retorna null

Status

  • fresh — dentro do TTL
  • stale — fora do TTL mas dentro do grace period
  • miss — nao encontrado

Instancias globais

FactoryNamespaceTTLStale Grace
getBrandCache()brand3600s (1h)3600s
getGamesCache()games300s (5min)300s

Camada 3 — GamesCacheService

Wrapper domain-specific sobre ServerCache para dados de jogos. Usa stale-while-revalidate com waitUntil() para revalidacao nao-bloqueante.

Padrao stale-while-revalidate

get(key)
|
├── fresh → retorna imediatamente
├── stale → retorna imediatamente + ctx.waitUntil(revalidate())
└── miss → fetch da API + cache + retorna

A revalidacao em background usa waitUntil() do Cloudflare Workers para nao bloquear a resposta.

Chaves de cache

O formato e {domain}/{segment}:

MetodoChaveDescricao
getHome()mybrand.com/homeLayout da homepage
getBase()mybrand.com/baseCategorias + providers
getAllGames()mybrand.com/all-gamesTodos os jogos (agregado)
getByCategory(slug)mybrand.com/category/slotsJogos por categoria
getByProvider(slug)mybrand.com/provider/pragmaticJogos por provider
getDetail(slug)mybrand.com/game/sweet-bonanzaDetalhe de jogo
search(params)usa all-gamesFiltro in-memory sobre cache

Busca

A busca de jogos nao faz request na API. Usa o cache de all-games e filtra in-memory via filterGames() do SDK — rapido e sem latencia de rede.

Purge

Via API route

POST /api/cache/games/purge
POST /api/dev/cache-clear

Programatico

import { purgeAllCaches, getAllCacheStats } from "~/services/cache.server";

// Purge tudo
await purgeAllCaches();

// Stats
const stats = getAllCacheStats();
// { brand: { hits, misses, ... }, games: { ... } }

Env vars

VariavelDescricao
PLATFORM_CACHE_POLICY_JSONPolitica serializada — injetada pelo front-ops em deploy-time. Ausente em dev local = bypass.
PLATFORM_CACHE_KVBinding KV para snapshots (provisionado automaticamente pelo front-ops).
CACHE_PURGE_SECRETSecret para o endpoint POST /api/cache/games/purge.

Arquivos

ArquivoDescricao
workers/middleware.tsSSR response cache + Smartico proxy
services/cache.server.tsServerCache base + factories (legacy)
services/games.cache.server.tsGamesCacheService (legacy, sendo substituido por platform-cache)