Skip to content

Contexto

O feed de notificações para telão (issue #146) precisa entregar notificações em tempo real. Duas abordagens concorrentes:

  1. Pool em memória: Worker mantém Map<churchId, WritableStream[]>; POST cria notificação e empurra para streams ativos.
  2. Polling no D1: SSE endpoint faz SELECT no D1 a cada 3s e emite notificações novas como eventos SSE.

Decisão

Usar polling no D1 (abordagem 2).

Consequências

Positivas

  • Funciona com múltiplas instâncias Worker — Cloudflare escala horizontalmente sem perder notificações
  • Sobrevive a deploysEventSource reconecta e o polling recomeça do lastCheck
  • Mais simples de implementar e testar (sem gerenciamento de pool)
  • Sem risco de memory leak por conexões órfãs

Negativas

  • Latência de ~3s entre criação e exibição no telão (vs tempo real com pool)
  • Custo de D1 queries: 1 query a cada 3s por conexão SSE ativa (~20/min)
  • CPU time: polling é I/O-bound (D1 wait), não CPU-bound — não impacta limite de 30s

Mitigações

  • 3s de latência é aceitável para telão de igreja (o pai já está sendo chamado presencialmente)
  • D1 query é indexada por (church_id, created_at) e retorna no máximo ~1 linha por polling
  • Se latência for problema no futuro, dá para migrar para pool sem quebrar clientes (EventSource é compatível)

Alternativas consideradas

AlternativaMotivo para rejeitar
Pool em memóriaPerde conexões em deploy; não escala com múltiplas instâncias Worker
WebSocket com Durable ObjectsDependência de infraestrutura mais complexa; superdimensionado para MVP
D1 + Durable Object como brokerComplexidade desnecessária para o volume de notificações esperado

Referências

Distribuído sob licença MIT.