Pular para o conteúdo principal

Design de Filas

Topologia

Tipos de Job

// Fila: runs
interface RunJob {
type: 'run';
tenantId: string;
integrationKey: string;
handlerKey: string;
direction: 'inbound' | 'outbound';
trigger: 'schedule' | 'manual';
runId: string;
}

// Fila: items
interface ItemJob {
type: 'item';
tenantId: string;
integrationKey: string;
handlerKey: string;
direction: 'inbound' | 'outbound';
runId: string;
itemId: string;
externalId: string;
payload: unknown;
}

Priorização de Jobs

Jobs recebem prioridade baseada no trigger (BullMQ: menor valor = maior prioridade):

TriggerPriorityJustificativa
webhook1Tempo real, resposta esperada pelo cliente externo
manual2Ação deliberada do usuário
queue3Consumo de fila externa
schedule5Agendamento periódico, tolera latência

Definido em packages/core/src/types/index.ts como constante JOB_PRIORITY, aplicado em todos os produtores (scheduler, webhook, run-worker fan-out).

Resiliência

MecanismoConfiguração
Retry3 tentativas, backoff exponencial (5s base)
DLQApós falha final, execution_items.dlq_at é preenchido
Fan-outFlowProducer parent/child — parent completa quando todos filhos terminam
ConcurrencyConfigurável por handler via configs.concurrency
Rate Limiting por handlerConfigurável via configs.rate_limit_per_minute
Rate Limiting por tenantSliding window 1.000 items/min, delay (não falha) ao exceder
Circuit BreakerPor integration_key: 5 falhas → open 30s → half-open → closed
PriorizaçãoWebhooks passam na frente de schedules na fila items
PausaPor handler, sem afetar outros
CacheRedis TTL 60s para types (reduz consultas ao PostgreSQL)
Batch ProcessingContrato /process-batch para reduzir overhead HTTP

Circuit Breaker

Circuit Breaker Redis-backed por integration_key com 3 estados:

closed ──(5 falhas)──→ open ──(30s)──→ half-open ──(2 sucessos)──→ closed

Quando o circuito está open, o item-worker faz fast-fail (throw imediato), e o job vai para retry. Isso evita que o Runner continue batendo em APIs externas que estão fora do ar.

Implementado em packages/core/src/resilience/circuit-breaker.ts.

Rate Limiter por Tenant

Sliding window Redis-backed que previne starvation de filas — um tenant com carga massiva (ex: 100k leads) não bloqueia itens de outros tenants.

  • Limite: 1.000 items/minuto por tenant (configurável)
  • Ao exceder: job é adiado em 5s (não falha, não perde)
  • Storage: Redis sorted set com auto-cleanup

Implementado em packages/core/src/resilience/rate-limiter.ts.

Cache Redis

Cache para reduzir consultas ao PostgreSQL em hot paths:

NamespaceChaveTTLUsado em
typesintegration_key60srun-worker, item-worker

Implementado em packages/core/src/cache/redis-cache.ts com pattern getOrFetch.