npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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.

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-autoscaler

Requer 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 de process.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 timers

O 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() usa timer.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