--- name: catcher-data-cache description: Use quando um app ou agente precisa consumir o Cache do Catcher (/v1/cloudcache/*). Redis dedicado em VM própria — DSN rediss:// com TLS, dois modos, resize, métricas, prefixo por tenant. homepage: https://catcher.one/produtos/cache docs: https://catcher.one/docs/cache api_base: https://data-api.catcher.one --- # Catcher — Cache Autenticação: `X-API-Key: ctc_…` (owner/admin). Base: https://data-api.catcher.one. Onboarding de key e conceitos gerais: https://catcher.one/skill. Referência navegável: https://catcher.one/docs/cache. # Cache — Redis gerenciado (`cloudcache`) > Rotas `/v1/cloudcache/*` · owner/admin · gated por `CLOUDCACHE_DEDICATED_ENABLED` > (off → `404 CLOUDCACHE_DEDICATED_UNAVAILABLE`) ## O que é **Redis gerenciado**, **dedicated-only**: cada cliente que quer cache provisiona a **própria instância Redis numa VM dedicada** (core/RAM/eviction/falha isolados, não compartilha com ninguém). Igual ao Database (decisão D1), é **control-plane only** — o seu app conecta **direto** no DSN via qualquer cliente Redis (`redis.UniversalClient`, ioredis, etc.); a Catcher **não** faz proxy de comando, então não há latência extra no caminho quente. > O modelo *shared* anterior (namespaces ACL sobre tiers `ephemeral`/`retained` > compartilhados) foi **aposentado em 2026-06-25**. As rotas > `…/cloudcache/namespaces*` não existem mais — hoje é só dedicated. ## O que dá pra fazer - **Estimar o custo** mensal antes de provisionar (dry-run, não cria nada). - **Provisionar** uma VM Redis dedicada (assíncrono) — a senha aparece **uma vez**. - **Listar / detalhar** suas instâncias (status + `dsn_host` quando `ready`). - **Redimensionar** (muda máquina/RAM), **pausar/religar** (corta o custo de compute), **reconciliar** o status com a VM real, **destruir**. - Ver **métricas** da VM (CPU/memória/etc.). ## Como funciona por dentro (na prática) - **Control-plane + VM real.** A API guarda a control-row no tenant DB; o Redis roda numa **VM Debian** dedicada (startup-script instala + configura o Redis por modo + hardening), **sem service account** (zero credencial na VM), servindo Redis **TLS (`rediss://`) na porta `6380`** com um cert **Let's Encrypt** para o host brandado da VM (DNS próprio, ou `.sslip.io` como fallback). - **Dois modos:** - **`mem_fast`** — `noeviction`, dimensionado por RAM, sub-ms, **mais caro**. Para cache que não pode perder chave sob pressão. - **`economico`** — `allkeys-lru`, RAM menor, **mais barato** — um miss cai no banco. É **eviction, não swap**. - **Provisionamento assíncrono.** `POST …/dedicated` responde com a instância `pending`/`provisioning` + a **senha (uma única vez)**; você faz poll de `GET …/dedicated/{id}` até `ready`, quando o `dsn_host` aparece. - **Conexão direta, por TLS.** A resposta traz `dsn_host` + `tls`. O endpoint é um **`rediss://` TLS roteável** (porta `6380`, cert Let's Encrypt, host brandado), então o DSN é `rediss://default:@` e o app conecta **de qualquer lugar** por TLS. (Um host interno plaintext usaria o esquema `redis://`.) ## Fluxo típico (end-to-end) ```bash KEY="X-API-Key: ctc_…" ; B=https://data-api.catcher.one ; JS='Content-Type: application/json' # 1. Veja o custo ANTES de criar (dry-run, não provisiona) curl -sX POST $B/v1/cloudcache/dedicated/estimate -H "$KEY" -H "$JS" \ -d '{"mode":"mem_fast","machine":"e2-medium","ram_mb":4096,"disk_gb":20,"region":"southamerica-east1"}' # → { "total_usd": 31.80, ... } # 2. Provisiona (assíncrono) — a senha vem UMA vez, guarde já curl -sX POST $B/v1/cloudcache/dedicated -H "$KEY" -H "$JS" \ -d '{"name":"prod","mode":"economico","machine":"e2-micro","ram_mb":1024,"disk_gb":20,"region":"southamerica-east1"}' # → { "instance": { "id":"…","status":"provisioning",… }, "password":"…" } # 3. Poll até ready (o dsn_host aparece quando pronto) curl -s $B/v1/cloudcache/dedicated/ -H "$KEY" | jq '.status, .dsn_host' # 4. No seu app: conecta direto por TLS (DSN = rediss://default:@) # e prefixe as chaves por tenant — ver a seção abaixo. ``` ## Referência de endpoints | Método | Rota | O que faz | |---|---|---| | `POST` | `/v1/cloudcache/dedicated/estimate` | Custo $/mês (`{mode,machine,ram_mb,disk_gb,region}`) — dry-run, não cria | | `POST` | `/v1/cloudcache/dedicated` | Provisiona (async) → `{instance, password}` (**senha uma vez**) | | `GET` | `/v1/cloudcache/dedicated` | Lista as instâncias | | `GET` | `/v1/cloudcache/dedicated/{id}` | Detalhe (status + `dsn_host` quando `ready`) | | `GET` | `/v1/cloudcache/dedicated/{id}/metrics` | Métricas da VM (CPU/memória/…) | | `POST` | `/v1/cloudcache/dedicated/{id}/resize` | Muda máquina/modo (`{machine,ram_mb}`; stop→resize→start) | | `POST` | `/v1/cloudcache/dedicated/{id}/stop` · `/start` | Pausa (corta custo de compute) / religa | | `POST` | `/v1/cloudcache/dedicated/{id}/reconcile` | Re-sincroniza o status com a VM real (não-disruptivo) | | `DELETE` | `/v1/cloudcache/dedicated/{id}` | Destrói a VM + a control-row | O custo aparece na **ativação ANTES de confirmar** (ex.: `e2-micro` econômico ~US$ 10,20/mês · `e2-medium` mem-fast ~US$ 31,80/mês). ## Isolamento por tenant (end-customers) Como o Cache é control-plane only (você conecta direto no DSN; não há proxy de comando), o isolamento por **cliente final** é por **convenção**, aplicada no SEU código: 1. **Prefixe** toda chave de um tenant com `t::` — ex. `t:acme:sessao:123`. 2. (Recomendado) crie um **usuário ACL do Redis por tenant**, restrito ao padrão `~t::*`, de modo que aquele tenant não leia/escreva fora do próprio prefixo. É o **mesmo `tenant_id`** que você usa no Database, Vector e Storage — o eixo transversal. Modelo completo + recomendações: **[Tenants](tenants.md)**. ## Códigos de erro do módulo `CLOUDCACHE_DEDICATED_UNAVAILABLE` (404 — feature desligada no ambiente, ou o wiring de GCP Compute não pôde ser construído). ## Gotchas - **A senha aparece uma única vez** (na criação) — guarde no seu secret manager. Para trocar, redimensione/recrie conforme a necessidade. - **Provisionar é assíncrono** — não trate a criação como pronta; faça poll de `GET …/dedicated/{id}` até `ready` (o `dsn_host` só aparece então). - **Endpoint TLS público (`rediss://` :6380)** — host brandado com cert Let's Encrypt; a conexão é criptografada. O esquema vem indicado pelo campo `tls` na resposta (`rediss://` quando público-TLS, `redis://` se host interno plaintext). - **`economico` é eviction, não swap** — sob pressão, chaves são descartadas (`allkeys-lru`) e o miss cai no banco. Use `mem_fast` quando não pode perder chave. - **`stop` corta o custo de compute** mas mantém a instância — útil para ambientes que não rodam 24/7. `reconcile` conserta uma control-row presa em `failed` após timeout de uma operação de control-plane, sem reiniciar a VM.