sistema-de-chamados/docs/convex-export-worker-loop.md
2025-11-18 11:58:58 -03:00

5.4 KiB

Convex — Loop do application::exports::worker (Nov/2025)

Documento técnico descrevendo o incidente que derrubava o backend Convex em produção e o passo a passo adotado para corrigir e evitar recorrências.


1. Resumo Executivo

  • Sintoma visível: o WebSocket wss://convex.esdrasrenan.com.br/api/1.29.2/sync caía em código 1006 a cada poucos segundos.
  • Causa raiz: um export agendado automaticamente pelo próprio Convex (application::exports::worker) reiniciava toda vez que o backend subia. Durante o “replay” o worker lia documentos (principalmente máquinas e cron jobs antigos) cujo shape já não batia com o esquema atual, causando panic em shape_inference/src/object.rs:67.
  • Impacto: o container sistema_convex_backend reiniciava em loop. npx convex deploy e qualquer CLI que dependesse do backend ficavam presos em start_push/wait_for_schema. O frontend ficava sem sincronização em tempo real.
  • Correção aplicada: saneamento manual do banco SQLite do Convex (limpeza de cron/exports/records incompatíveis) seguido de um restart completo. O export pendente finalizou com sucesso e o backend estabilizou.

2. Detecção

  1. docker service logs --tail 400 sistema_convex_backend mostrava:
    • Mensagens repetidas do export (Export gg20vw5b... progress: ...).
    • Panics em application::exports::worker ou common::errors com mensagens Object with shape ... not in Shape ....
  2. No navegador e no npx convex deploy, as conexões WebSocket encerravam com código 1006.

3. Diagnóstico / Root Cause Analysis

  1. O Convex self-hosted mantém exports incrementais. Quando o backend reinicia, o worker reprocessa o export pendente.
  2. Em sistema_convex_data, a tabela documents possuía registros legados:
    • Cron hours-usage-alerts-hourly (já removido do código).
    • Documentos de máquinas com metadata/customFields maiores do que o shape compilado.
  3. Assim que o export lia esses documentos “fora do shape”, o Convex fazia panic!, derrubando o processo principal.
  4. Como o export jamais completava, o worker reiniciava e o ciclo se repetia.

4. Procedimento de Recuperação (Runbook)

⚠️ Sempre trabalhar em cima do volume sistema_convex_data.
Todos os comandos abaixo devem ser executados como root na VPS.

4.1. Parar o backend e fazer backup

docker service scale sistema_convex_backend=0

# Guardar uma cópia datada
docker run --rm -v sistema_convex_data:/convex/data \
  busybox sh -c 'ts=$(date +%Y%m%d%H%M%S); cp /convex/data/db.sqlite3 /convex/data/db.sqlite3.backup-$ts'

4.2. Inspecionar o banco (SQLite)

Usamos a imagem nouchka/sqlite3, montando o volume:

docker run --rm -it -v sistema_convex_data:/convex/data nouchka/sqlite3 /convex/data/db.sqlite3

Consultas úteis:

-- Verificar o export pendente
SELECT json_value FROM documents
WHERE json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly';

-- Identificar documentos de máquinas problemáticos
SELECT hex(id), hex(table_id), ts
FROM documents
WHERE json_extract(json_value, '$._id') = 'jn7aq2647e6g69qbrg7q9n6aas7sxqje';

4.3. Sanear dados incompatíveis

  1. Cron legado
    DELETE FROM documents
    WHERE hex(table_id) = 'C24DDDBFBA00025744D7672E2AC74F91'
      AND json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly';
    
  2. Máquina fora do shape
    • Remover índices ligados ao documento:
      DELETE FROM indexes WHERE document_id = X'AB88C43B8D0326EBC40F74D4CA564F9E';
      
    • Remover o documento em si:
      DELETE FROM documents WHERE id = X'AB88C43B8D0326EBC40F74D4CA564F9E';
      
  3. (Opcional) Qualquer export/cron adicional pode ser limpado usando o mesmo padrão: DELETE na tabela documents e correspondentes em indexes.

4.4. Subir o backend e validar

docker service scale sistema_convex_backend=1
docker service logs --tail 400 -f sistema_convex_backend

Critérios de sucesso:

  • Logs mostram application::exports::worker ... completed e, logo após, No exports requested or in progress.
  • Não existem novas linhas Caught error/shape_inference.
  • WebSocket /api/1.29.2/sync volta a responder 101 Switching Protocols.

5. Pós-incidente / Prevenção

  1. Desabilitar jobs pesados por padrão: já deixamos REPORTS_CRON_ENABLED=false e AUTO_PAUSE_ENABLED=false nas variáveis. Mantê-las assim até que o Convex publique um fix oficial.
  2. Sempre limpar exports antigos antes de alterar schema: se um export for rodado manualmente, aguardá-lo completar antes de editar tabelas grandes (machines, ticketWorkSessions etc.).
  3. Monitorar logs após deploys: docker service logs sistema_convex_backend | rg exports::worker ajuda a verificar se há novos exports presos.
  4. Documentar qualquer alteração direta no SQLite: registrar no repositório (neste arquivo) os comandos executados, garantindo um histórico completo.

6. Referências rápidas

  • Volume Convex: sistema_convex_data
  • Banco: /convex/data/db.sqlite3
  • Contêiner SQLite: nouchka/sqlite3
  • Parar/Subir serviço: docker service scale sistema_convex_backend=0|1
  • Arquivo anterior de referência: /convex/data/db.sqlite3.pre-export-clean-20251118123551

Última revisão: 18/11/2025 — sanado por remoção dos registros incompatíveis e rerun bem-sucedido do export gg20vw5b479d9a2jprjpe3pxg57vk9wa.