Ir al contenido
use-cases / crontab-per-branch / hero
CRON · GIT · PROGRAMACIONES POR RAMA

Un crontab por rama, desplegado con el código

Incluye `.hoody/crontab` en el repo junto a tus jobs. Cuando el script de despliegue arranca un contenedor para `main`, `feature/billing-v2` o cualquier rama de preview, hace PUT de ese archivo a la API de Cron del nuevo contenedor. La programación viaja con la rama — y desaparece cuando la rama desaparece.

Leer la API de Cron
use-cases / crontab-per-branch / mechanism

Cómo `.hoody/crontab` se convierte en una programación real

Cada contenedor de rama ejecuta Hoody Cron. El script de despliegue lee el crontab incluido y lo envía con PUT al endpoint raw-crontab del nuevo contenedor. El contenedor ejecuta la programación que describe el archivo — nada más, nada menos.

deploy.sh · enviado por CI
shell · cliente
#!/bin/sh
# Aprovisiona un contenedor nuevo para esta rama.
BRANCH=$(git branch --show-current)
CTR=$(hoody containers create --from main-snapshot)

# Reemplaza el crontab del contenedor por el del repo.
curl -X PUT --data-binary @.hoody/crontab \
  -H "Content-Type: text/plain" \
  https://$CTR-cron-1.hoody.com/users/root/crontab

# Listo. La programación de la rama vive en su contenedor.
echo "deployed $BRANCH → $CTR"
PUT /users/root/crontab
cron · servidor
# Endpoint raw-crontab de Hoody Cron — reemplaza el archivo entero de forma atómica.
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: el daemon de cron se recarga, la programación queda activa en menos de un segundo.

El crontab son datos que la rama transporta, no estado que el servidor cron recuerde. Borra el contenedor y no queda ninguna entrada que limpiar — el archivo se fue con el disco.

use-cases / crontab-per-branch / powers

Tres cosas que dejas de hacer

Cuando la programación es un archivo en el repo, desaparecen tres categorías de trabajo.

VERSIONADO

Las programaciones viajan en el mismo diff que el código

Cuando cambias `billing-rollup.sh` a v2, la nueva programación llega en el mismo pull request. Quien revisa ve la línea cron justo al lado del script. Revierte un commit y la programación se revierte con él.

DESMONTAJE

Borra la rama y el cron se va con ella

Los contenedores de rama son efímeros. Cuando haces merge o cierras la rama, desmontas el contenedor. El crontab vivía dentro, así que la programación desaparece sin que nadie limpie — no hay servidor cron compartido sosteniendo entradas obsoletas.

AISLAMIENTO

El experimento no puede dispararse en staging

Un job experimental por hora en `experiment/llm-rollups` corre en su propio contenedor con su propio sistema de archivos. El daemon cron de staging nunca lo ve; el de producción tampoco. No hay guardas `if BRANCH_ENV` dentro de los propios jobs.

use-cases / crontab-per-branch / compare

Crontab compartido vs crontab por rama

El modelo estándar de "un crontab gestionado por ops" y el modelo ligado a la rama fallan en direcciones opuestas. Mismo job, radio de impacto muy distinto.

EJECRONTAB COMPARTIDOCRONTAB POR RAMA
Fuente de verdad
wiki de ops + rol de ansiblela programación vive en otro repo distinto al script
.hoody/crontab en el repojunto al script que invoca la línea cron
Añadir un job
merge del código → ping a ops → SSH al host de crondos sistemas tienen que coordinarse, a mano
edita el archivo, push, despliegaun diff, un merge, un despliegue
Aislamiento por rama
if [ "$ENV" = staging ]; then …cada job conoce todos los entornos
contenedor por ramasin flag de entorno dentro del script
Limpieza
acordarse de quitar la línealas entradas obsoletas se acumulan durante años
rama borrada = cron borradoel sistema de archivos desaparece, la programación también
Experimentos
el crontab de producción es el únicocualquier prueba arriesga dispararse en prod
rama spike = crontab spikese dispara solo en su contenedor

La diferencia no es una funcionalidad — es dónde vive la programación. Un archivo que la rama transporta, frente a una fila de una tabla compartida que la rama toma prestada.

use-cases / crontab-per-branch / capacity

Lo que Hoody Cron te ofrece de verdad

Cron por contenedor es una superficie REST real — tres familias de endpoints, sintaxis cron estándar, aislamiento total por usuario. Cifras de la spec de la API de Cron, no benchmarks inventados.

  1. CRONTAB POR CONTENEDOR1

    Cada contenedor de rama tiene su propio crontab por usuario. Haz PUT del archivo entero, GET para recuperarlo, reemplázalo de forma atómica. Sin tabla de programación compartida por detrás.

  2. FAMILIAS DE ENDPOINTS3

    Crontab raw (GET/PUT), entradas gestionadas (POST/PATCH/DELETE con UUIDs y `expires_at`), y listado por usuario. Elige la que tu script de despliegue necesite.

  3. EXPRESIONES CRON DE 5 CAMPOS5

    El estándar `min hora día mes dow` más macros: `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. La misma sintaxis que ya usa tu `.hoody/crontab`.

Según la API de Hoody Cron: GET/PUT /users/[user]/crontab y POST/PATCH/DELETE /users/[user]/entries en la URL del servicio cron de cada contenedor.

use-cases / crontab-per-branch / punchline

La programación vive junto al código que la ejecuta, en el mismo contenedor, en la misma rama.

antes · dos sistemas que recordarahora · un archivo en el repo
LO QUE TENÍAS ANTESprogramación en ops/ansible · código en app/ · nunca coincidíanhaz merge del PR y luego abre un ticket para actualizar el host de cron
LO QUE TIENES AHORAPUT @.hoody/crontab → cron-1.[branch].hoody.comun PUT, un contenedor, una programación, una rama
Leer la API de Cron
use-cases / crontab-per-branch / replaces

Lo que esto reemplaza

Seis sitios donde solía vivir la programación cron, ninguno junto al código. El crontab ligado a la rama los hace todos redundantes.

  • crontab compartido de producciónUn archivo en un host de cron alrededor del cual cada equipo tenía que coordinarse
  • sincronización manual de la config de cronRol de Ansible / manifiesto de Puppet aplicado fuera de banda respecto a tus merges de código
  • programaciones de GitHub Actions ancladas a mainProgramaciones atadas a la rama por defecto, invisibles para el trabajo de feature y los previews
  • "acuérdate de actualizar cron al hacer merge"Un punto de checklist humano — lo único que se interpone entre tú y una entrada obsoleta
  • repo separado de configuración cronUn segundo repo cuyo único trabajo era ir por detrás del que tenía el código real
  • migraciones programadas con Atlas/LiquibaseHerramientas de migración haciendo de programador porque no había mejor sitio donde meterlo
use-cases / crontab-per-branch / cta

Deja de sincronizar programaciones entre sistemas. Incluye el crontab en el repo. Deja que la rama lo transporte.

Leer los docs de Cron
use-cases / crontab-per-branch / related

Lee los otros