chore: añade directorio dev/ con issues y funciones implementadas
Tracking de issues completados (jupyter tools) y funciones implementadas (specs de diseño ya resueltas).
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# Scheduling / Cron
|
||||
|
||||
Gap identificado en el registry. Reimplementar desde cero.
|
||||
|
||||
Los pipelines se lanzan manualmente o desde la TUI. No hay scheduling recurrente
|
||||
dentro del registry. Complementario a Dagu — estas funciones son primitivas
|
||||
componibles, no un scheduler completo.
|
||||
|
||||
## Funciones a implementar
|
||||
|
||||
### parse_cron_expr
|
||||
|
||||
- **Dominio:** core
|
||||
- **Lang:** Go
|
||||
- **Purity:** pure
|
||||
- **Signature:** `ParseCronExpr(expr string) (CronSchedule, error)`
|
||||
- **Retorno:** CronSchedule con campos Minute, Hour, DayOfMonth, Month, DayOfWeek parseados
|
||||
- **Descripcion:** Parser de expresiones cron estandar (5 campos). Soporta `*`, rangos (`1-5`), listas (`1,3,5`), pasos (`*/15`), y aliases (@hourly, @daily, @weekly, @monthly). No soporta seconds ni years (no es Quartz).
|
||||
- **Algoritmo:**
|
||||
1. Check aliases (@hourly → "0 * * * *", etc)
|
||||
2. Split por espacios, validar 5 campos
|
||||
3. Por campo: expandir `*` a rango completo, parsear rangos/listas/pasos
|
||||
4. Validar limites (minute 0-59, hour 0-23, etc)
|
||||
- **Deps:** `strings`, `strconv`, `fmt` (solo stdlib)
|
||||
- **Tests:**
|
||||
- "*/15 * * * *" → minutos [0,15,30,45]
|
||||
- "0 9 * * 1-5" → 9am weekdays
|
||||
- "@daily" → "0 0 * * *"
|
||||
- "0 9 1,15 * *" → dia 1 y 15 a las 9
|
||||
- Expresion invalida → error descriptivo
|
||||
- Campo fuera de rango → error
|
||||
|
||||
### next_cron_time
|
||||
|
||||
- **Dominio:** core
|
||||
- **Lang:** Go
|
||||
- **Purity:** pure
|
||||
- **Signature:** `NextCronTime(schedule CronSchedule, after time.Time) time.Time`
|
||||
- **Retorno:** Proximo time.Time que cumple el schedule despues de `after`
|
||||
- **Descripcion:** Calcula la proxima ejecucion de un cron schedule. Avanza minuto a minuto desde `after` hasta encontrar un match. Limit de 366 dias para evitar loops infinitos en schedules imposibles.
|
||||
- **Algoritmo:**
|
||||
1. Truncar `after` al minuto, avanzar 1 minuto
|
||||
2. Check month → si no match, avanzar al primer dia del proximo mes valido
|
||||
3. Check day of month y day of week → si no match, avanzar al proximo dia
|
||||
4. Check hour → si no match, avanzar a la proxima hora
|
||||
5. Check minute → si no match, avanzar al proximo minuto
|
||||
- **Deps:** `time`
|
||||
- **Tests:**
|
||||
- "0 * * * *" desde 14:30 → 15:00
|
||||
- "0 9 * * 1" desde viernes → proximo lunes 9:00
|
||||
- "0 0 29 2 *" → proximo 29 de febrero
|
||||
- Schedule imposible → panic o error despues de limit
|
||||
|
||||
### cron_ticker
|
||||
|
||||
- **Dominio:** infra
|
||||
- **Lang:** Go
|
||||
- **Purity:** impure (goroutine + channel + time)
|
||||
- **Signature:** `CronTicker(schedule CronSchedule, ctx context.Context) <-chan time.Time`
|
||||
- **Retorno:** Channel que emite un time.Time en cada tick del schedule
|
||||
- **Descripcion:** Crea un ticker que emite en los momentos definidos por el cron schedule. Usa time.NewTimer internamente, recalculando el proximo tick despues de cada emision. Se detiene al cancelar el context.
|
||||
- **Deps:** `time`, `context`
|
||||
- **Tests:**
|
||||
- Ticker con schedule "* * * * *" emite cada minuto (test con clock mock o schedule rapido)
|
||||
- Context cancel detiene el ticker
|
||||
- Channel se cierra al cancelar
|
||||
|
||||
### parse_cron_expr (Python)
|
||||
|
||||
- **Dominio:** core
|
||||
- **Lang:** Python
|
||||
- **Purity:** pure
|
||||
- **Signature:** `parse_cron_expr(expr: str) -> dict`
|
||||
- **Retorno:** `{"minute": list[int], "hour": list[int], "day_of_month": list[int], "month": list[int], "day_of_week": list[int]}`
|
||||
- **Descripcion:** Misma semantica que Go. Dict en vez de struct.
|
||||
- **Tests:** Mismos casos que Go
|
||||
|
||||
### next_cron_time (Python)
|
||||
|
||||
- **Dominio:** core
|
||||
- **Lang:** Python
|
||||
- **Purity:** pure
|
||||
- **Signature:** `next_cron_time(schedule: dict, after: datetime) -> datetime`
|
||||
- **Descripcion:** Misma semantica que Go.
|
||||
- **Tests:** Mismos casos que Go
|
||||
|
||||
## Tipo a implementar
|
||||
|
||||
### CronSchedule (Go)
|
||||
|
||||
- **Dominio:** core
|
||||
- **Lang:** Go
|
||||
- **Algebraic:** product
|
||||
- **Definicion:**
|
||||
```go
|
||||
type CronSchedule struct {
|
||||
Minute []int
|
||||
Hour []int
|
||||
DayOfMonth []int
|
||||
Month []int
|
||||
DayOfWeek []int
|
||||
Raw string // expresion original
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user