Files
multica/server/internal/service/cron.go
Jiayuan Zhang f94b0100cd refactor(autopilot): remove broken concurrency policies and fix multiple bugs (#1048)
Remove the concurrency_policy system (skip/queue/replace) — skip had an
orphan bug that permanently blocked triggers, queue didn't actually queue,
and replace didn't cancel running tasks. Every trigger now simply executes.

Bug fixes:
- Listener now handles in_review status (was silently ignored)
- Issue deletion fails linked autopilot runs before DELETE (prevents orphans)
- ComputeNextRun rejects invalid timezones instead of silent UTC fallback
- dispatchCreateIssue post-commit failures now properly fail the run

Reliability:
- Scheduler recovers lost triggers on startup (crash recovery)
- New index on autopilot_run(issue_id) for deletion lookups
- Migration 043 cleans up historical orphaned/skipped/pending runs
2026-04-15 13:48:21 +08:00

35 lines
954 B
Go

package service
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
)
// cronParser accepts standard 5-field cron expressions.
var cronParser = cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
// ComputeNextRun parses a cron expression and returns the next fire time
// in the given timezone.
func ComputeNextRun(cronExpr, timezone string) (time.Time, error) {
sched, err := cronParser.Parse(cronExpr)
if err != nil {
return time.Time{}, fmt.Errorf("parse cron: %w", err)
}
loc, err := time.LoadLocation(timezone)
if err != nil {
return time.Time{}, fmt.Errorf("invalid timezone %q: %w", timezone, err)
}
return sched.Next(time.Now().In(loc)), nil
}
// ValidateTimezone returns an error if the timezone string is not recognized.
func ValidateTimezone(timezone string) error {
_, err := time.LoadLocation(timezone)
if err != nil {
return fmt.Errorf("invalid timezone %q: %w", timezone, err)
}
return nil
}