Sybren A. Stüvel 02fac6a4df Change Go package name from git.blender.org to projects.blender.org
Change the package base name of the Go code, from
`git.blender.org/flamenco` to `projects.blender.org/studio/flamenco`.

The old location, `git.blender.org`, has no longer been use since the
[migration to Gitea][1]. The new package names now reflect the actual
location where Flamenco is hosted.

[1]: https://code.blender.org/2023/02/new-blender-development-infrastructure/
2023-08-01 12:42:31 +02:00

104 lines
2.8 KiB
Go

package sleep_scheduler
// SPDX-License-Identifier: GPL-3.0-or-later
import (
"strings"
"time"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/pkg/api"
)
// scheduledWorkerStatus returns the expected worker status at the given date/time.
func scheduledWorkerStatus(now time.Time, sched *persistence.SleepSchedule) api.WorkerStatus {
if sched == nil {
// If there is no schedule at all, the worker should be awake.
return api.WorkerStatusAwake
}
tod := persistence.MakeTimeOfDay(now)
if !sched.IsActive {
return api.WorkerStatusAwake
}
if sched.DaysOfWeek != "" {
weekdayName := strings.ToLower(now.Weekday().String()[:2])
if !strings.Contains(sched.DaysOfWeek, weekdayName) {
// There are days configured, and today is not a sleeping day.
return api.WorkerStatusAwake
}
}
beforeStart := sched.StartTime.HasValue() && tod.IsBefore(sched.StartTime)
afterEnd := sched.EndTime.HasValue() && !tod.IsBefore(sched.EndTime)
if beforeStart || afterEnd {
// Outside sleeping time.
return api.WorkerStatusAwake
}
return api.WorkerStatusAsleep
}
func cleanupDaysOfWeek(daysOfWeek string) string {
trimmed := strings.TrimSpace(daysOfWeek)
if trimmed == "" {
return ""
}
daynames := strings.Fields(trimmed)
for idx, name := range daynames {
daynames[idx] = strings.ToLower(strings.TrimSpace(name))[:2]
}
return strings.Join(daynames, " ")
}
// Return a timestamp when the next scheck for this schedule is due.
func calculateNextCheck(now time.Time, schedule *persistence.SleepSchedule) time.Time {
// calcNext returns the given time of day on "today" if that hasn't passed
// yet, otherwise on "tomorrow".
calcNext := func(tod persistence.TimeOfDay) time.Time {
nextCheck := tod.OnDate(now)
if nextCheck.Before(now) {
nextCheck = nextCheck.AddDate(0, 0, 1)
}
return nextCheck
}
nextChecks := []time.Time{
// Always check at the end of the day.
endOfDay(now),
}
// No start time means "start of the day", which is already covered by
// yesterday's "end of the day" check.
if schedule.StartTime.HasValue() {
nextChecks = append(nextChecks, calcNext(schedule.StartTime))
}
// No end time means "end of the day", which is already covered by today's
// "end of the day" check.
if schedule.EndTime.HasValue() {
nextChecks = append(nextChecks, calcNext(schedule.EndTime))
}
next := earliestTime(nextChecks)
return next
}
func earliestTime(timestamps []time.Time) time.Time {
earliest := timestamps[0]
for _, timestamp := range timestamps[1:] {
if timestamp.Before(earliest) {
earliest = timestamp
}
}
return earliest
}
// endOfDay returns the next midnight at UTC.
func endOfDay(now time.Time) time.Time {
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).AddDate(0, 0, 1)
}