Skip to content

Commit 320aa6b

Browse files
committed
feat(trogon-cron): add scheduler, tooling, and coverage
1 parent 290461a commit 320aa6b

File tree

24 files changed

+22324
-37
lines changed

24 files changed

+22324
-37
lines changed

CRON

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
Informacion extraida con Claude
2+
CRON Job con NATS
3+
4+
┌─────────────────────────────────────────────────────────┐
5+
│ CRON Definitions │
6+
│ "0 * * * *" → subject: cron.backup │
7+
│ "*/5 * * * *" → subject: cron.health-check │
8+
│ "0 0 * * *" → subject: cron.report │
9+
└───────────────────────┬─────────────────────────────────┘
10+
11+
12+
┌─────────────────┐
13+
│ Scheduler │
14+
│ (reads crons, │
15+
│ fires on time) │
16+
└────────┬────────┘
17+
│ publish
18+
19+
┌─────────────────┐
20+
│ NATS │
21+
└────────┬────────┘
22+
23+
┌────────────┼────────────┐
24+
▼ ▼ ▼
25+
┌────────────┐ ┌──────────┐ ┌──────────┐
26+
│ Worker A │ │ Worker B │ │ Worker C │
27+
│ (backup) │ │ (health) │ │ (report) │
28+
└────────────┘ └──────────┘ └──────────┘
29+
30+
Flujo
31+
32+
1. Defines el job con un schedule y un subject NATS
33+
2. El Scheduler evalúa el schedule y cuando toca, publica en el subject
34+
3. El Worker está suscrito al subject y ejecuta la tarea
35+
36+
Ejemplo de definición
37+
38+
[[jobs]]
39+
name = "backup"
40+
schedule = "0 * * * *"
41+
subject = "cron.backup"
42+
payload = { db = "main" }
43+
44+
Mensaje que llega al Worker
45+
46+
{
47+
"job": "backup",
48+
"fired_at": "2026-02-23T10:00:00Z",
49+
"payload": { "db": "main" }
50+
}
51+
52+
53+
Flujo de trabajo
54+
55+
┌─────────────────────────────────────────────────────────┐
56+
│ 1. DEFINES EL JOB │
57+
│ │
58+
│ schedule = "0 * * * *" │
59+
│ subject = "cron.backup" │
60+
│ payload = { db: "main" } │
61+
└───────────────────────┬─────────────────────────────────┘
62+
63+
64+
┌─────────────────────────────────────────────────────────┐
65+
│ 2. SCHEDULER │
66+
│ │
67+
│ - Lee las definiciones │
68+
│ - Evalúa el tiempo (cron expression) │
69+
│ - Cuando toca → publica mensaje en NATS │
70+
└───────────────────────┬─────────────────────────────────┘
71+
│ publish("cron.backup", payload)
72+
73+
┌─────────────────────────────────────────────────────────┐
74+
│ 3. NATS │
75+
│ │
76+
│ Recibe el mensaje y lo distribuye │
77+
│ a los suscritos al subject │
78+
└───────────────────────┬─────────────────────────────────┘
79+
│ subscribe("cron.backup")
80+
81+
┌─────────────────────────────────────────────────────────┐
82+
│ 4. WORKER │
83+
│ │
84+
│ - Recibe el mensaje │
85+
│ - Ejecuta la tarea (backup, report, etc.) │
86+
│ - Responde con resultado (opcional) │
87+
└─────────────────────────────────────────────────────────┘
88+
89+
En resumen
90+
91+
┌──────┬───────────┬──────────────────────────────────────┐
92+
│ Paso │ Quién │ Qué hace │
93+
├──────┼───────────┼──────────────────────────────────────┤
94+
│ 1 │ Tú │ Defines schedule + subject + payload │
95+
├──────┼───────────┼──────────────────────────────────────┤
96+
│ 2 │ Scheduler │ Dispara el mensaje a la hora exacta │
97+
├──────┼───────────┼──────────────────────────────────────┤
98+
│ 3 │ NATS │ Enruta el mensaje al worker correcto │
99+
├──────┼───────────┼──────────────────────────────────────┤
100+
│ 4 │ Worker │ Ejecuta la tarea │
101+
└──────┴───────────┴──────────────────────────────────────┘
102+
103+
El worker no sabe nada de cron, solo escucha un subject de NATS y actúa. Eso lo hace muy flexible.
104+
105+
106+
El payload es la información extra que el scheduler le manda al worker para que sepa con qué datos ejecutar la tarea.
107+
108+
Scheduler publica:
109+
{
110+
"job": "backup",
111+
"fired_at": "2026-02-23T10:00:00Z",
112+
"payload": { "db": "main", "path": "/backups" } ← esto es el payload
113+
}
114+
115+
Sin payload:
116+
- El worker solo sabe que tiene que correr
117+
- Tiene que tener toda la config hardcodeada adentro
118+
119+
Con payload:
120+
- El worker recibe datos dinámicos
121+
- Puedes usar el mismo worker para diferentes configuraciones
122+
123+
Ejemplo práctico:
124+
125+
job 1: subject="cron.backup" payload={ db: "main" }
126+
job 2: subject="cron.backup" payload={ db: "analytics" }
127+
128+
El mismo worker cron.backup hace backup de diferentes bases de datos dependiendo del payload que recibe. No necesitas dos workers distintos.
129+
130+
En resumen: el payload es opcional pero muy útil para hacer los workers reutilizables.
131+
132+
133+
134+
135+

CRON-web

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
Una tarea cron es una operación automatizada programada para ejecutarse en horas o intervalos específicos en sistemas basados en Unix, incluidos Linux y macOS. El término «cron» proviene de «chronos», la palabra griega para tiempo, y representa una de las herramientas más fundamentales de automatización de tareas en la informática moderna.
2+
3+
Las tareas cron permiten a administradores de sistemas y desarrolladores programar operaciones repetitivas sin intervención manual —desde copias de seguridad de bases de datos y rotación de registros hasta generación de informes y mantenimiento del sistema. Al definir cuándo y con qué frecuencia debe ejecutarse una tarea, las tareas cron garantizan que las operaciones críticas se ejecuten de forma coherente y fiable, formando así la columna vertebral de las operaciones automatizadas en millones de servidores en todo el mundo.
4+
5+
Ya sea ejecutar un script de limpieza simple cada día a medianoche u orquestar canalizaciones de datos complejas entre varios sistemas, las tareas cron proporcionan la infraestructura de programación que mantiene las operaciones digitales en funcionamiento las 24 horas del día.
6+
7+
Componentes principales de las tareas cron
8+
9+
(crond) : El servicio en segundo plano que funciona de manera continua y comprueba la tabla de programación cada minuto para determinar qué tareas deben ejecutarse.
10+
11+
Crontab (tabla cron) : El archivo de configuración donde los usuarios definen sus tareas programadas; cada línea representa una tarea separada y su planificación.
12+
13+
Expresión cron : El formato de especificación temporal compuesto por cinco o seis campos (minuto, hora, día del mes, mes, día de la semana y, opcionalmente, año) que define cuándo debe ejecutarse una tarea.
14+
15+
Comando de la tarea : El script, programa o comando que se ejecuta cuando llega el momento programado.
16+
17+
Comprender la sintaxis de las expresiones cron
18+
19+
Las expresiones cron usan un formato de cinco campos para especificar la programación:
20+
21+
* * * * * command-to-execute
22+
23+
│ │ │ │ │
24+
25+
│ │ │ │ └─── Día de la semana (0-7, tanto 0 como 7 representan domingo)
26+
27+
│ │ │ └────── Mes (1-12)
28+
29+
│ │ └───────── Día del mes (1-31)
30+
31+
│ └──────────── Hora (0-23)
32+
33+
└─────────────── Minuto (0-59)
34+
35+
Ejemplos comunes:
36+
37+
0 2 * * * – Ejecutar diariamente a las 02:00
38+
*/15 * * * * – Ejecutar cada 15 minutos
39+
0 0 * * 0 – Ejecutar semanalmente los domingos a medianoche
40+
0 9-17 * * 1-5 – Ejecutar cada hora de 9:00 a 17:00 en días laborables
41+
42+
43+
44+
Los operadores utilizados en las expresiones cron permiten definir horarios complejos y específicos:
45+
46+
Asterisco (*): Representa todos los valores posibles para un campo.
47+
48+
Coma (,): Permite especificar una lista de valores.
49+
50+
Guión (-): Define un rango de valores.
51+
52+
Barra inclinada (/): Indica intervalos o pasos a seguir dentro de un rango.
53+
54+
55+
56+
Para poder definir los cron jobs para un usuario usamos el comando siguiente:
57+
58+
crontab -e
59+
60+
Esto nos abrirá el archivo de los cron jobs en un editor de texto usable por terminal. Los trabajos se tienen que definir en una sintaxis que veremos un poco más adelante.
61+
62+
Revisar cron jobs activos por usuario
63+
64+
Si en cualquier momento necesitas saber qué tareas tienes en un momento dado configuradas puedes usar el comando:
65+
66+
crontab -l
67+
68+
Esto nos permitirá listar las tareas actuales de un usuario.
69+
70+
Ejemplos de cron jobs reales y prácticos
71+
72+
Lo mejor para poder entender la sintaxis de los cron jobs es mostrar algunos ejemplos típicos. Los siguientes ejemplos prácticos serían casos reales de uso de las tareas del cron.
73+
74+
0 2 * * * /home/user/backup.sh
75+
76+
El comando anterior serviría para ejecutar un script llamado backup.sh cada día a las 2 de la mañana.
77+
78+
0 * * * * rm -rf /tmp/*
79+
80+
Esta segunda programación indicaría que se tienen que limpiar archivos temporales (borrando lo que hay en la carpeta /tmp), cada hora.
81+
82+
El comando anterior lo usarías para actualizar paquetes de un servidor Ubuntu, o cualquier otro basado en Debian, todos los domingos a las 4 de la mañana
83+
84+
Para crear una aplicación tipo Cron Job con NATS, lo más eficiente es utilizar NATS JetStream para la persistencia y la programación de mensajes, en lugar de intentar forzar el "Core NATS" a manejar tiempos. JetStream permite definir políticas de retención, entregas garantizadas y, mediante el uso de KV (Key-Value) o durabilidad, programar tareas periódicas.
85+
Pasos para Crear un Cron Job con NATS
86+
87+
Instalar NATS y JetStream: Asegúrese de tener un servidor NATS configurado con JetStream habilitado, por ejemplo, usando Docker: docker run -p 4222:4222 -ti nats:latest -js.
88+
Configurar un Stream: Defina un stream en JetStream donde se publicarán los mensajes de "trabajo" (ej. tasks_stream).
89+
Productor (Cron Job): Una aplicación cliente publica un mensaje en el stream tasks_stream a intervalos regulares, simulando el cron job (ej. usando la librería node-cron en Node.js o cron en Go para disparar la publicación).
90+
Consumidor (Trabajador): Una aplicación se suscribe al stream utilizando un consumidor duradero (Durable Consumer). Este trabajador procesará el mensaje. NATS asegura que, si el trabajador cae, al reiniciar procesará el mensaje pendiente.
91+
92+
Ejemplo Básico (Concepto en Go/Node)
93+
94+
Productor: nc.Publish("cron.job.update", []byte("ejecutar_tarea")) (Llamado cada X tiempo).
95+
Consumidor: js.PullSubscribe("cron.job.update", "durable-worker") (Procesa el mensaje).
96+
97+
98+
99+
Alternativa NATS KV
100+
101+
El CRON externo actualiza una clave en NATS KV
102+
El worker escucha los cambios en esa clave y ejecuta la tarea cada vez que el valor cambia
103+
104+
Esta solucion permite que la programacion y la ejecucion esten desacopladas, distriuidas totalmente por NATS

rsworkspace/Cargo.lock

Lines changed: 76 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)