@luxorbots/discloud-autoscaler
v0.2.0
Published
Agent leve de autoscaling de memória para aplicações Node.js hospedadas na Discloud. Coleta métricas locais e reporta sinais de tendência para o luxor-autoscaler-manager.
Maintainers
Readme
@luxorbots/discloud-autoscaler
Agent leve de autoscaling de memória para aplicações Node.js hospedadas na Discloud. Faz parte do ecossistema Luxor.
Esta biblioteca não decide nada sobre RAM. Ela coleta métricas de memória do próprio processo, calcula uma tendência local e reporta um sinal ao luxor-autoscaler-manager — que é o único componente autorizado a falar com a API da Discloud e efetivamente alterar RAM.
Instalação
npm install @luxorbots/discloud-autoscalerRequer Node.js 22 ou superior.
Uso com register (mais simples)
import "@luxorbots/discloud-autoscaler/register";Um único import de efeito colateral: cria o autoscaler a partir das variáveis de ambiente e chama start() imediatamente. Ideal para adicionar no topo do arquivo de entrada do bot sem tocar em mais nada.
Uso programático
import { createAutoscaler } from "@luxorbots/discloud-autoscaler";
const autoscaler = createAutoscaler();
autoscaler.start();
// ...
await autoscaler.stop();createAutoscaler(options?)lê e valida a configuração (por padrão deprocess.env) e retorna uma instância pronta para uso.start()é idempotente: chamadas repetidas nunca criam múltiplos timers.stop()cancela o timer de monitoramento e aborta qualquer requisição HTTP em andamento.
Configuração
Toda a configuração vem de variáveis de ambiente, validadas na criação do autoscaler (createAutoscaler()/register). Configuração inválida lança AutoscalerConfigError com uma lista legível de todos os problemas encontrados.
| Variável | Obrigatória | Default | Descrição |
| --------------------------- | ------------------- | ------- | ---------------------------------------------------------------------------------------- |
| AUTOSCALE_ENABLED | não | false | Liga/desliga o Agent. Se false, start() não faz nada. |
| AUTOSCALE_MANAGER_URL | sim (se habilitado) | — | URL base do luxor-autoscaler-manager. |
| AUTOSCALE_MANAGER_TOKEN | sim (se habilitado) | — | Token do Agent (não é o DISCLOUD_TOKEN). |
| AUTOSCALE_UP_THRESHOLD | não | 90 | % de uso de memória para sinalizar candidato a upscale. |
| AUTOSCALE_DOWN_THRESHOLD | não | 50 | % de uso de memória para sinalizar candidato a downscale. |
| AUTOSCALE_UP_SAMPLES | não | 3 | Amostras consecutivas acima do threshold para gerar SCALE_UP_CANDIDATE. |
| AUTOSCALE_DOWN_SAMPLES | não | 30 | Amostras consecutivas abaixo do threshold para gerar SCALE_DOWN_CANDIDATE. |
| AUTOSCALE_CHECK_INTERVAL | não | 30000 | Intervalo do ciclo de coleta, em ms (mínimo 5000). |
| AUTOSCALE_REQUEST_TIMEOUT | não | 5000 | Timeout da requisição HTTP ao Manager, em ms (mínimo 200, ≤ AUTOSCALE_CHECK_INTERVAL). |
| AUTOSCALE_LOG_LEVEL | não | info | debug | info | warn | error | silent. |
| AUTOSCALE_DEBUG | não | false | Se true, força nível de log debug independente de AUTOSCALE_LOG_LEVEL. |
Validações aplicadas: thresholds entre 0 e 100, upThreshold > downThreshold, amostras inteiras ≥ 1, checkInterval/requestTimeout com mínimos seguros, managerUrl precisa ser uma URL válida, managerUrl/managerToken obrigatórios quando AUTOSCALE_ENABLED=true.
O Agent não declara o próprio appId: quem identifica o app perante o Manager é o AUTOSCALE_MANAGER_TOKEN, que já está associado a um appId desde a emissão (npm run issue-agent-token no luxor-autoscaler-manager).
Arquitetura (Agent)
MemorySampler -> lê process.memoryUsage() e converte para MB
SampleWindow -> janela circular limitada de amostras (sem crescimento infinito)
ThresholdEvaluator -> decide um SINAL (SCALE_UP_CANDIDATE | SCALE_DOWN_CANDIDATE | STABLE), nunca uma ação
AutoscalerManagerClient -> envia o sinal ao Manager (fetch + timeout + retry com backoff exponencial)
Autoscaler -> orquestra o ciclo, com guarda contra múltiplos timersO Agent nunca inventa o limite de RAM do app: percentuais de uso só são calculados quando o Manager informa esse limite na resposta de POST /v1/agents/metrics (ramLimitMb), e o Agent guarda esse valor em cache em memória (nunca em ENV). Até que o limite seja conhecido, o ThresholdEvaluator retorna STABLE.
Comportamento em falhas
- Qualquer erro dentro do ciclo de execução (
execute()) é capturado e logado — nunca propaga para o processo hospedeiro. - Se o Manager estiver offline ou inacessível, o Agent tenta novamente com backoff exponencial (até um limite de tentativas) e depois desiste silenciosamente até o próximo ciclo — o bot continua funcionando normalmente.
- Retry só ocorre para falhas tipicamente temporárias (timeout, erro de rede, HTTP 408/429/500/502/503/504). Erros do cliente (400/401/403/404) não são reprocessados.
start()usatimer.unref(): o timer de monitoramento nunca impede o processo Node.js de encerrar sozinho.stop()cancela o timer e aborta a requisição em andamento, se houver.
Desenvolvimento
npm install
npm run lint
npm run typecheck
npm test
npm run build