a03675113a
- .claude/agents/fn-orquestador/SKILL.md - .claude/commands/fn_claude.md - .claude/rules/INDEX.md - .claude/rules/cpp_apps.md - .claude/rules/ids_naming.md - CHANGELOG.md - apps/dag_engine/README.md - apps/dag_engine/api.go - apps/dag_engine/dags_migrated/example.yaml - apps/dag_engine/dags_migrated/example_lineage_tracking.yaml - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.8 KiB
3.8 KiB
Scheduler — Cron expression parsing, matching, scheduling
Tag: scheduler. Grupo de funciones para trabajar con expresiones cron: parsear, validar coincidencias, calcular proximo run, traducir a lenguaje humano. Lo consume apps/dag_engine + cpp/apps/dag_engine_ui (tab Schedule). Crece a medida que se anaden nuevos formatos (Quartz, k8s CronJob, etc.).
Filtro MCP: mcp__registry__fn_search query="" tag="scheduler".
Funciones del grupo
| ID | Firma corta | Que hace |
|---|---|---|
| parse_cron_expr_go_core | ParseCronExpr(expr string) (CronSchedule, error) |
Parsea expresion cron de 5 campos a struct expandido. Soporta *, rangos, listas, pasos y aliases @hourly/@daily/@weekly/@monthly/@yearly. |
| cron_match_go_core | CronMatch(s CronSchedule, t time.Time) bool |
True si un instante coincide con un schedule. Compara los 5 campos. |
| next_cron_time_go_core | NextCronTime(s CronSchedule, after time.Time) time.Time |
Proxima ejecucion despues de un instante. Salta minuto a minuto. Zero time si no hay match en 366 dias. |
| cron_explain_go_core | CronExplain(expr string) string |
Traduce expresion cron a frase humana corta ("every 15 minutes", "daily at 09:00", "weekdays at HH:MM"). |
Ejemplo canonico end-to-end
Trabajar con un schedule completo: parsear, calcular proximo run, explicarlo al usuario.
package main
import (
"fmt"
"time"
"fn-registry/functions/core"
)
func main() {
expr := "*/15 * * * *"
// 1. Parsear
sched, err := core.ParseCronExpr(expr)
if err != nil {
panic(err)
}
// 2. Proximo run
next := core.NextCronTime(sched, time.Now())
fmt.Printf("next run: %s\n", next.Format(time.RFC3339))
// 3. Explicacion humana
fmt.Printf("schedule: %s (%s)\n", expr, core.CronExplain(expr))
// -> schedule: */15 * * * * (every 15 minutes)
// 4. Verificacion puntual
if core.CronMatch(sched, time.Now()) {
fmt.Println("would trigger now")
}
}
Fronteras del grupo
NO cubre:
- Persistencia de schedules (vive en BD de quien lo use:
apps/dag_engine/store/). - Spawn/wait de procesos (eso es
process_*_go_infra). - Sintaxis Quartz extendida con
?o anos. Solo soporta los 5 campos estandar + aliases@hourly/@daily/@weekly/@monthly/@yearly. - Timezones — todo se evalua en
time.Localdel proceso. Si necesitas TZ explicita, parsea fuera y traduce. - Sintaxis especial de Kubernetes CronJob (segundos opcionales en el primer campo).
- DAG orchestration / DAG runs (consume estas funciones via
apps/dag_engine).
Prerequisitos
- Go stdlib. Sin dependencias externas en ninguna funcion del grupo.
- Tipo compartido
cron_schedule_go_core(struct conMinute/Hour/Day/Month/Weekdaycomo[]intexpandidos).
Notas
cron_matchesta tageadapendiente-usar— sin consumidores actuales aparte del propio paquete. Si se incorpora anext_cron_timecomo optimizacion -> quitar tag.cron_explainmantiene contrato simple: si el patron no encaja en los reconocidos, devuelve el expr crudo sin error. Apto para UI fallback.- Para anadir nueva funcion al grupo: anadir tag
scheduleraltags:del frontmatter, anadir fila a la tabla arriba, actualizarNendocs/capabilities/INDEX.md.
Consumidores actuales
apps/dag_engine—parse_cron_expr_go_core,next_cron_time_go_core(+cron_ticker_go_infraadyacente).cpp/apps/dag_engine_ui— tab Schedule consume/api/dagsexpuesto por dag_engine; via backend usa estas funciones.- Candidato futuro:
cron_explain_go_coreendag_engine/api/dags(anadir camposchedule_humanal JSON response) para que la UI no tenga que duplicar logica.