Pular para o conteúdo
use-cases / crontab-per-branch / hero
CRON · GIT · AGENDAMENTOS POR BRANCH

Um crontab por branch, implantado junto com o código

Versione `.hoody/crontab` no repositório, ao lado dos seus jobs. Quando o script de deploy sobe um contêiner para `main`, `feature/billing-v2` ou qualquer branch de preview, ele faz PUT desse arquivo na Cron API do novo contêiner. O agendamento embarca com a branch — e desaparece quando ela some.

Ler a Cron API
use-cases / crontab-per-branch / mechanism

Como `.hoody/crontab` vira um agendamento real

Cada contêiner de branch roda Hoody Cron. O script de deploy lê o crontab versionado e faz PUT no endpoint raw-crontab do novo contêiner. O contêiner roda o agendamento que o arquivo descreve — nada mais, nada menos.

deploy.sh · enviado pelo CI
shell · cliente
#!/bin/sh
# Provisiona um contêiner novo para esta branch.
BRANCH=$(git branch --show-current)
CTR=$(hoody containers create --from main-snapshot)

# Substitui o crontab do contêiner pelo que está no repositório.
curl -X PUT --data-binary @.hoody/crontab \
  -H "Content-Type: text/plain" \
  https://$CTR-cron-1.hoody.com/users/root/crontab

# Pronto. O agendamento da branch vive no contêiner dela.
echo "deployed $BRANCH → $CTR"
PUT /users/root/crontab
cron · servidor
# Endpoint raw-crontab do Hoody Cron — substitui o arquivo inteiro atomicamente.
PUT /users/root/crontab HTTP/1.1
Host: ctr_4d72b9-cron-1.hoody.com
Content-Type: text/plain

0 2 * * * /srv/jobs/billing-rollup-v2.sh
*/15 * * * * /srv/jobs/sync-stripe.py
@hourly curl -fsS http://localhost/healthz
*/5 * * * * /srv/jobs/diff-v1-v2.sh

HTTP/1.1 200 OK
# 200 OK: daemon cron recarrega, agendamento ativo em menos de um segundo.

O crontab é dado que a branch carrega, não estado que o servidor cron lembra. Apague o contêiner e não sobra entrada para limpar — o arquivo foi com o disco.

use-cases / crontab-per-branch / powers

Três coisas que você deixa de fazer

Quando o agendamento vira um arquivo no repositório, três categorias de trabalho desaparecem.

VERSIONAMENTO

Agendamentos viajam no mesmo diff do código

Quando você muda `billing-rollup.sh` para v2, o novo agendamento entra no mesmo pull request. O revisor vê a linha cron bem ao lado do script. Reverta um commit e o agendamento reverte junto.

TEARDOWN

Apague a branch e o cron vai junto

Contêineres de branch são efêmeros. Quando você faz merge ou fecha a branch, derruba o contêiner. O crontab vivia dentro dele, então o agendamento desaparece sem zelador — não há servidor cron compartilhado segurando entradas obsoletas.

ISOLAMENTO

O experimento não dispara em staging

Um job experimental por hora em `experiment/llm-rollups` roda no próprio contêiner com seu próprio sistema de arquivos. O daemon cron de staging nunca o vê; o de produção nunca o vê. Não existe `if BRANCH_ENV` dentro dos próprios jobs.

use-cases / crontab-per-branch / compare

Crontab compartilhado vs crontab por branch

O modelo padrão de "um crontab gerenciado pelo ops" e o modelo amarrado à branch falham em direções opostas. Mesmo job, raio de impacto bem diferente.

EIXOCRONTAB COMPARTILHADOCRONTAB POR BRANCH
Fonte da verdade
wiki do ops + role ansibleagendamento vive em outro repositório, longe do script
.hoody/crontab no repositórioao lado do script que a linha cron invoca
Adicionar um job
merge do código → ping no ops → SSH no host crondois sistemas precisam concordar, manualmente
edita o arquivo, faz push, faz deployum diff, um merge, um deploy
Isolamento de branch
if [ "$ENV" = staging ]; then …todo job conhece todo ambiente
contêiner por branchsem flag de ambiente dentro do script
Limpeza
lembrar de remover a linhaentradas obsoletas se acumulam por anos
branch apagada = cron apagadoo sistema de arquivos sumiu, o agendamento sumiu
Experimentos
o crontab de produção é o únicoqualquer teste arrisca disparar em prod
branch spike = crontab spikedispara só no contêiner dela

A diferença não é um recurso — é onde o agendamento mora. Um arquivo que a branch carrega, contra uma linha em uma tabela compartilhada da qual a branch toma emprestado.

use-cases / crontab-per-branch / capacity

O que o Hoody Cron realmente entrega

Cron por contêiner é uma superfície REST de verdade — três famílias de endpoints, sintaxe cron padrão, isolamento total por usuário. Números da especificação da Cron API, não benchmarks inventados.

  1. CRONTAB POR CONTÊINER1

    Cada contêiner de branch tem o próprio crontab por usuário. PUT no arquivo inteiro, GET para recuperar, substitua atomicamente. Sem tabela de agendamento compartilhada por trás.

  2. FAMÍLIAS DE ENDPOINTS3

    Crontab raw (GET/PUT), entradas gerenciadas (POST/PATCH/DELETE com UUIDs e `expires_at`) e listagem por usuário. Escolha o que seu script de deploy precisa.

  3. EXPRESSÕES CRON DE CAMPOS5

    Padrão `min hora dia mes dow` mais macros: `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. A mesma sintaxe que seu `.hoody/crontab` já usa.

Conforme a Hoody Cron API: GET/PUT /users/[user]/crontab e POST/PATCH/DELETE /users/[user]/entries na URL do serviço cron de cada contêiner.

use-cases / crontab-per-branch / punchline

O agendamento vive ao lado do código que roda nele, no mesmo contêiner, na mesma branch.

antes · dois sistemas para lembrardepois · um arquivo no repositório
O QUE VOCÊ COSTUMAVA TERagendamento em ops/ansible · código em app/ · nunca concordavamfaça o merge do PR, depois abra um ticket para atualizar o host cron
O QUE VOCÊ TEM AGORAPUT @.hoody/crontab → cron-1.[branch].hoody.comum PUT, um contêiner, um agendamento, uma branch
Ler a Cron API
use-cases / crontab-per-branch / replaces

O que isso substitui

Seis lugares onde o agendamento cron costumava morar, nenhum deles ao lado do código. O crontab atrelado à branch torna todos eles redundantes.

  • crontab compartilhado de produçãoUm arquivo em um host cron que toda equipe tinha que coordenar
  • sincronização manual de configuração cronRole Ansible / manifesto Puppet aplicado fora do fluxo dos seus merges de código
  • agendamentos do GitHub Actions presos ao mainAgendamentos atrelados à branch padrão, invisíveis para trabalho de feature e previews
  • "lembre de atualizar o cron quando der merge"Um item de checklist humano — a única coisa entre você e uma entrada obsoleta
  • repositório separado de configuração cronUm segundo repositório cujo único trabalho era ficar atrás do que tem o código de verdade
  • migrações agendadas Atlas/LiquibaseFerramentas de migração fazendo papel de agendador porque não havia lugar melhor para isso morar
use-cases / crontab-per-branch / cta

Pare de sincronizar agendamentos entre sistemas. Versione o crontab. Deixe a branch carregar.

use-cases / crontab-per-branch / related

Leia os outros