blocky/config/schedules.go

108 lines
2.2 KiB
Go

package config
import (
"context"
"time"
"github.com/0xERR0R/blocky/evt"
"github.com/0xERR0R/blocky/log"
"github.com/sirupsen/logrus"
)
const (
refreshInterval = time.Minute
)
// Schedules is the list of schedule for the defined blacklist
type Schedules map[string][]Schedule
// Refresh update Schedule to set the Active field boolean
func (s Schedules) Refresh(ctx context.Context, nowFunc func() time.Time) {
logger := log.PrefixedLog("refresh_schedules")
s.setActive(nowFunc, logger) // initial schedules refresh (after blocky start)
syncSchedulesWithSystemTime(s, nowFunc, logger)
ticker := time.NewTicker(refreshInterval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
s.setActive(nowFunc, logger)
case <-ctx.Done():
return
}
}
}
func syncSchedulesWithSystemTime(s Schedules, nowFunc func() time.Time, logger *logrus.Entry) {
waitTime := getWaitTimeBeforeNextMinute()
time.Sleep(waitTime)
s.setActive(nowFunc, logger) // now in sync with system time
}
func getWaitTimeBeforeNextMinute() time.Duration {
return time.Until(
time.Date(
time.Now().Year(),
time.Now().Month(),
time.Now().Day(),
time.Now().Hour(),
time.Now().Minute()+1, 0, 0,
time.Now().Location(),
),
)
}
func (s Schedules) setActive(nowFunc func() time.Time, logger *logrus.Entry) {
if nowFunc == nil {
nowFunc = time.Now
}
for group, schedList := range s {
for i, schedule := range schedList {
active := false
activeStr := "inactive"
if schedule.isActive(nowFunc) {
active = true
activeStr = "active"
}
if schedule.Active != active {
s[group][i] = Schedule{
Days: schedule.Days,
HoursRanges: schedule.HoursRanges,
Active: active,
}
activeFlag := 0
if active {
activeFlag = 1
}
evt.Bus().Publish(evt.SchedulesActive, group, activeFlag)
logger.Infof("group %s is now %s", group, activeStr)
}
}
}
}
// IsActive checks if the schedules of the group is active at the current time
func (s Schedules) IsActive(group string, nowFunc func() time.Time) bool {
if nowFunc == nil {
nowFunc = time.Now
}
for _, schedule := range s[group] {
if schedule.isActive(nowFunc) {
return true
}
}
return false
}