0.31.0
Added
- P2-A1: Cron catch-up пропущенных тиков —
recalcAllJobsпересчитывает не толькоnilnext_run_at, но и просроченные. Дляevery— сдвиг наnow + duration; дляcron—sched.Next(now); дляat— оставляет для немедленного исполнения. Унификация формата времени на RFC3339 для корректного SQL-сравненияnext_run_at <= now(). Логирование catch-up событий. - P2-A2: Schedule-kind
"at"парсинг и валидация —ValidateScheduleExpr(kind, expr)— общая функция валидации (at → RFC3339/ISO, every → duration ≥ 1s, cron → robfig parser). Вызывается вCronTool.addAction,CronHandler.Create/Update. Невалидные строки типа «вечером» отклоняются. Мёртвый кодparseTimeудалён. - P2-A3: saveCheckpoint — восстановление после рестарта — таблица
actor_checkpoints(миграция 030).SessionActor.busy(atomic bool) выставляется приhandleInbound.saveCheckpointпишет busy-флаг при shutdown. При стартеAgentLoop.recoverBusyCheckpointsнаходит прерванные сессии и очищает. Checkpoint удаляется при idle timeout. Store-методыSaveActorCheckpoint,ListBusyCheckpoints,ClearActorCheckpoint(SQLite, PostgreSQL, DualStore). - P2-A4: Heartbeat tick неблокирующий — каждый
tickAgentзапускается в отдельной горутине сsync.WaitGroup. Context timeout 2 минуты на каждый агент.recover()в каждой горутине — защита от panic.
Fixed
- Формат времени cron: переход с
"2006-01-02 15:04:05"наtime.RFC3339для совместимости сstore.Now()→ корректное сравнениеnext_run_at <= now()в SQL. ComputeNextRunAtдля"at"— теперь парсит выражение черезparseFlexibleTimeвместо возврата сырой строки.