feat(infra): add scheduler and worker-generate standalone processes
Extract monitoring recovery/inspection workers and schedule dispatch into a dedicated scheduler process. Add worker-generate process for article generation and template-assist queue consumption. Introduce shared/schedule runtime for cron-based worker lifecycle management. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cron "github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
var cronParser = cron.NewParser(
|
||||
cron.SecondOptional |
|
||||
cron.Minute |
|
||||
cron.Hour |
|
||||
cron.Dom |
|
||||
cron.Month |
|
||||
cron.Dow |
|
||||
cron.Descriptor,
|
||||
)
|
||||
|
||||
func Parse(cronExpr string) (cron.Schedule, error) {
|
||||
trimmed := strings.TrimSpace(cronExpr)
|
||||
if trimmed == "" {
|
||||
return nil, fmt.Errorf("cron expression is required")
|
||||
}
|
||||
|
||||
schedule, err := cronParser.Parse(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse cron expression %q: %w", trimmed, err)
|
||||
}
|
||||
return schedule, nil
|
||||
}
|
||||
|
||||
func ComputeNextRun(cronExpr string, startAt, endAt *time.Time, now time.Time) (*time.Time, error) {
|
||||
schedule, err := Parse(cronExpr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notBefore := now.In(time.Local)
|
||||
if startAt != nil {
|
||||
start := startAt.In(time.Local)
|
||||
if start.After(notBefore) {
|
||||
notBefore = start
|
||||
}
|
||||
}
|
||||
|
||||
next := schedule.Next(notBefore.Add(-time.Nanosecond)).Round(0)
|
||||
if next.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
if endAt != nil && next.After(endAt.In(time.Local)) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &next, nil
|
||||
}
|
||||
|
||||
func IsRunAllowed(runAt time.Time, startAt, endAt *time.Time) bool {
|
||||
runAt = runAt.In(time.Local)
|
||||
if startAt != nil && runAt.Before(startAt.In(time.Local)) {
|
||||
return false
|
||||
}
|
||||
if endAt != nil && runAt.After(endAt.In(time.Local)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user