From e2dde8510a0855ebf3a36fb94ac7b116e9a18368 Mon Sep 17 00:00:00 2001 From: esdrasrenan Date: Wed, 10 Dec 2025 00:01:49 -0300 Subject: [PATCH] fix(convex): adicionar logs obrigatorios em cron jobs para evitar shape_inference errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adicionar console.log no inicio de autoEndInactiveSessions (liveChat.ts) - Adicionar console.log no inicio de cleanupStalePendingPolicies (usbPolicy.ts) - Documentar problema de shape_inference e solucao em OPERATIONS.md (Secao 11) - Atualizar .env.example com BETTER_AUTH_SECRET de 32+ caracteres O shape_inference do Convex self-hosted falha ao unificar arrays vazios (logLines: []) com arrays de strings (logLines: ["msg"]). Garantindo que todo cron job produza ao menos um log, evitamos o conflito de tipos. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .env.example | 2 +- convex/liveChat.ts | 2 + convex/usbPolicy.ts | 2 + docs/OPERATIONS.md | 157 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 3bd8cbc..7ae99f3 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,7 @@ NEXT_PUBLIC_APP_URL=http://localhost:3000 # Better Auth BETTER_AUTH_URL=http://localhost:3000 -BETTER_AUTH_SECRET=change-me-in-prod +BETTER_AUTH_SECRET=your-secret-key-at-least-32-chars-long # Convex (dev server URL) NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:3210 diff --git a/convex/liveChat.ts b/convex/liveChat.ts index f1c416e..2361784 100644 --- a/convex/liveChat.ts +++ b/convex/liveChat.ts @@ -747,6 +747,8 @@ const INACTIVITY_TIMEOUT_MS = 5 * 60 * 1000 export const autoEndInactiveSessions = mutation({ args: {}, handler: async (ctx) => { + // Log obrigatorio para evitar shape_inference errors com logLines vazios + console.log("cron: autoEndInactiveSessions iniciado") const now = Date.now() const cutoffTime = now - INACTIVITY_TIMEOUT_MS diff --git a/convex/usbPolicy.ts b/convex/usbPolicy.ts index 99b7fa4..c642372 100644 --- a/convex/usbPolicy.ts +++ b/convex/usbPolicy.ts @@ -309,6 +309,8 @@ export const cleanupStalePendingPolicies = mutation({ staleThresholdMs: v.optional(v.number()), }, handler: async (ctx, args) => { + // Log obrigatorio para evitar shape_inference errors com logLines vazios + console.log("cron: cleanupStalePendingPolicies iniciado") const thresholdMs = args.staleThresholdMs ?? 3600000 // 1 hora por padrao const now = Date.now() const cutoff = now - thresholdMs diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index b553804..9b555a6 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -236,3 +236,160 @@ Resumo das mudanças aplicadas no painel administrativo para simplificar “Usu - Agentes (dispositivos): provisionamento automático; edição detalhada/vínculo principal em Admin ▸ Dispositivos. Arquivo: `src/components/admin/devices/admin-devices-overview.tsx`. > Observação operacional: mantivemos o provisionamento de dispositivos inalterado (token/e‑mail técnico), e o acesso web segue apenas para pessoas. A unificação é de UX/gestão. + +## 10) Convex Self-Hosted — Otimizacao de Memoria (OOM) + +### Problema + +O Convex self-hosted carrega **todas as versoes de todos os documentos** em memoria (SQLite in-memory). Com heartbeats de dispositivos a cada 30s, cada `patch()` criava uma nova versao do documento `machines`, causando: + +- Acumulo exponencial: ~3500 versoes para ~65 maquinas +- Uso de memoria crescente: 8-10 GiB para poucos dispositivos +- Crashes por OOM e desconexoes WebSocket (codigo 1006) + +### Solucao Implementada (2025-12-09) + +**1. Separacao de heartbeats em tabela dedicada** + +Nova tabela `machineHeartbeats` armazena apenas `lastHeartbeatAt`: + +```typescript +// convex/schema.ts +machineHeartbeats: defineTable({ + machineId: v.id("machines"), + lastHeartbeatAt: v.number(), +}).index("by_machine", ["machineId"]), +``` + +**2. Heartbeat inteligente** + +A funcao `heartbeat` agora: +- SEMPRE atualiza `machineHeartbeats` (documento pequeno, upsert) +- SO atualiza `machines` quando ha mudancas reais (hostname, OS, metadata, status) + +```typescript +// Verificar se ha mudancas reais nos dados +const hasMetadataChanges = Object.keys(metadataPatch).length > 0 +const hasHostnameChange = args.hostname && args.hostname !== machine.hostname +const needsMachineUpdate = hasMetadataChanges || hasHostnameChange || ... + +// So atualizar machines se houver mudancas reais +if (needsMachineUpdate) { + await ctx.db.patch(machine._id, { ...patch }) // SEM lastHeartbeatAt +} +``` + +**3. Filtragem de campos volumetricos** + +`INVENTORY_BLOCKLIST` remove campos que mudam frequentemente ou sao muito grandes: +- `software` (lista de programas instalados) +- `extended` (dados estendidos) + +Hardware (CPU, memoria, placa-mae) **permanece visivel** em `/admin/devices`. + +### Resultado + +| Metrica | Antes | Depois | +|---------|-------|--------| +| Uso de memoria | 8-10 GiB | 4-5 GiB | +| Versoes por maquina | ~50/dia | ~2-3/dia | +| Percentual RAM (20 GiB) | 40-50% | 20-25% | + +### Monitoramento + +```bash +# Verificar uso de memoria +docker stats --no-stream --format 'table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}' | grep convex + +# Verificar OOM kills recentes +journalctl -k | grep -i 'oom\|killed' | tail -20 + +# Restart do servico se necessario +docker service update --force sistema_convex_backend +``` + +### Limites de Memoria (Docker Swarm) + +Configurado em `stack.yml`: + +```yaml +services: + convex_backend: + deploy: + resources: + limits: + memory: 20G + reservations: + memory: 8G +``` + +Para alterar via CLI: +```bash +docker service update --limit-memory 20G --reserve-memory 8G sistema_convex_backend +``` + +## 11) Convex Self-Hosted — Erros de shape_inference (WebSocket 1006) + +### Problema + +O Convex self-hosted usa um sistema de **shape inference** para otimizar queries e exports. Quando documentos da mesma tabela tem campos com tipos incompativeis, o sistema falha ao unificar os "shapes". + +**Sintoma observado:** +- WebSocket desconectando com codigo `1006` (abnormal closure) +- Logs com erro `shape_inference` repetidos +- Export em loop: `Export beginning...` repetindo indefinidamente + +**Causa raiz:** +A tabela `_scheduled_job_logs` acumulou milhares de registros de cron jobs. Alguns tinham: +- `logLines: []` (array vazio) +- `logLines: ["mensagem de log"]` (array com strings) + +O shape inference nao consegue unificar `Array` com `Array`, causando falha continua. + +### Solucao Implementada (2025-12-09) + +**1. Garantir que cron jobs sempre produzam logs** + +Adicionamos `console.log()` obrigatorio no inicio de cada handler de cron: + +```typescript +// convex/liveChat.ts - autoEndInactiveSessions +handler: async (ctx) => { + console.log("cron: autoEndInactiveSessions iniciado") + // ... resto do codigo +} + +// convex/usbPolicy.ts - cleanupStalePendingPolicies +handler: async (ctx, args) => { + console.log("cron: cleanupStalePendingPolicies iniciado") + // ... resto do codigo +} +``` + +**2. Por que funciona** + +Com o log obrigatorio, **todos** os registros de `_scheduled_job_logs` terao: +- `logLines: ["cron: iniciado", ...]` + +Isso garante consistencia de tipos (sempre `Array`), evitando o conflito de shapes. + +### Arquivos Modificados + +- `convex/liveChat.ts:751` — log no inicio de `autoEndInactiveSessions` +- `convex/usbPolicy.ts:313` — log no inicio de `cleanupStalePendingPolicies` + +### Monitoramento + +```bash +# Verificar se ha erros de shape_inference nos logs +ssh root@154.12.253.40 "docker service logs sistema_convex_backend 2>&1 | grep -i 'shape_inference' | tail -10" + +# Verificar status dos cron jobs no dashboard +# Acesse: convex-admin.esdrasrenan.com.br > Scheduled Jobs +``` + +### Notas + +- Este e um bug interno do Convex self-hosted que pode ser corrigido em versoes futuras +- A solucao de adicionar logs obrigatorios e um workaround que nao afeta performance +- Se novos cron jobs forem adicionados, **sempre incluir um console.log no inicio**