Sessenta contêineres em um servidor
Um servidor bare-metal roda dezenas a centenas de contêineres Hoody. KSM e dedup do BTRFS deixam o custo marginal perto de zero.
Seu SaaS deixa cada cliente agendar a própria geração de relatórios. O design ingênuo é um scheduler compartilhado, IDs de cliente no payload do job, dedos cruzados pra ninguém deixar ninguém sem comer. O design Hoody dá a cada tenant seu próprio contêiner e seu próprio serviço hoody-cron.
Três estados do ciclo de vida, uma API HTTP. PROVISION adiciona entradas, cron ticks as executam, DELETE suspende. O cron de cada tenant vive em seu próprio contêiner — sem fila compartilhada, sem risco de vizinho barulhento.
Cada contêiner de cliente expõe a API HTTP do hoody-cron. Para definir o agendamento, você substitui o crontab com um único PUT. Sem fila compartilhada, sem faixa de prioridade, sem config de scheduler para reimplantar.
# POST managed entry for acme-corp tenant
POST acme-cron.hoody.com/users/root/entries
Content-Type: application/json
{
"schedule": "0 9 * * *",
"command": "/usr/local/bin/digest.sh",
"comment": "daily digest",
"enabled": true
}HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "7d3f2a1b-8c4e-4f9a-b2d5",
"schedule": "0 9 * * *",
"schedule_human": "At 09:00",
"enabled": true,
"user": "root"
}O endpoint substitui o crontab inteiro de forma atômica. Entradas removidas são reportadas de volta para que seu control plane possa auditar deriva. O cron de cada tenant vive dentro do próprio contêiner; nada sobre o agendamento da acme-corp é visível para a globex-saas, e um job descontrolado em um contêiner não pode matar de fome o scheduler em outro.
Três propriedades caem do design de graça, porque o isolamento é o substrato, não uma feature que você escreveu.
Quando o scrape.js da initech-inc trava, o digest das 9h da acme-corp ainda dispara. Crontabs diferentes, árvores de processo diferentes, filesystems diferentes.
Faça POST de uma nova entrada e o serviço hoody-cron do tenant pega imediatamente. Sem scheduler central para recarregar, sem broadcast para enviar.
Quando a globex-saas pergunta por que o rollup das 18h rodou duas vezes, você lê o log de um contêiner — não um grep em scheduler compartilhado por nove máquinas.
Três eixos onde o design antigo cobra imposto do seu time e o design Hoody simplesmente não cobra.
A coluna antiga é o que todo time escreve da primeira vez que entrega agendamento multi-tenant. A coluna nova é o que você entrega quando a plataforma dá a cada tenant seu próprio contêiner por padrão.
O que uma única máquina bare-metal Hoody faz quando cada cliente ganha o próprio crontab.
Sessenta contêineres de cliente em um nó bare-metal, cada um com seu próprio serviço hoody-cron rodando. Sem scheduler compartilhado pra fazer gargalo.
Da requisição PUT ao primeiro tique do novo agendamento, observado numa frota de 60 contêineres num nó típico de 64 cores.
Literalmente não existe fila compartilhada, faixa de prioridade ou thread de scheduler pela qual dois tenants competem. Isolamento é o substrato.
Os números de capacidade são valores típicos observados num nó bare-metal de 64 cores / 256GB rodando densidade padrão de contêineres Hoody. A capacidade real depende dos orçamentos de CPU e memória por tenant e do trabalho que cada cron job faz. O zero em filas entre tenants é estrutural, não um benchmark.
O cron de um cliente não pode matar de fome o de outro porque eles não estão no mesmo crontab.
As arquiteturas que times constroem para compartilhar um crontab entre tenants. A Hoody coloca cada tenant no próprio crontab — sem roteador, sem fila de fairness, sem vizinho barulhento.
Pare de escrever tenant_id em todo lugar. Dê a cada cliente seu próprio contêiner e deixe o cron fazer o que o cron sempre fez, em isolamento.