added optional jitter to schedule filter

This commit is contained in:
BroodjeAap 2023-03-25 14:37:02 +00:00
parent 1490fb10bd
commit b393da1773
3 changed files with 51 additions and 2 deletions

View file

@ -1220,7 +1220,13 @@ func TriggerSchedule(watchID WatchID, web *Web, scheduleID *FilterID) {
// getCronDebugResult parses the cron schedule string and logs any errors
func getCronDebugResult(filter *Filter) {
_, err := cron.ParseStandard(filter.Var1)
scheduleSplit := strings.Split(filter.Var1, "+")
scheduleTrimmed := strings.TrimSpace(scheduleSplit[0])
_, err := cron.ParseStandard(scheduleTrimmed)
if err != nil {
filter.Log(err)
}
_, err = getJittersFromScheduleString(filter.Var1)
if err != nil {
filter.Log(err)
}

View file

@ -2,6 +2,9 @@ package web
import (
"errors"
"math/rand"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
@ -66,3 +69,27 @@ func buildFilterTree(filters []Filter, connections []FilterConnection) {
}
*/
}
func getJittersFromScheduleString(scheduleString string) ([]time.Duration, error) {
split := strings.Split(scheduleString, "+")
split = split[1:]
durations := []time.Duration{}
if len(split) == 0 {
return durations, nil
}
rand.Seed(time.Now().UnixMilli())
for _, jitter := range split {
trimmed := strings.TrimSpace(jitter)
duration, err := time.ParseDuration(trimmed)
if err != nil {
return durations, err
}
duration = time.Duration(float64(duration.Nanoseconds()) * rand.Float64())
durations = append(durations, duration)
}
return durations, nil
}

View file

@ -91,7 +91,9 @@ func (web *Web) addCronJobIfCronFilter(filter *Filter, startup bool) {
if filter.Var2 != nil && *filter.Var2 == "no" {
return
}
entryID, err := web.cron.AddFunc(filter.Var1, func() { TriggerSchedule(filter.WatchID, web, &filter.ID) })
scheduleSplit := strings.Split(filter.Var1, "+")
scheduleTrimmed := strings.TrimSpace(scheduleSplit[0])
entryID, err := web.cron.AddFunc(scheduleTrimmed, func() { web.addCronJitter(filter.WatchID, filter) })
if err != nil {
if startup {
web.startupWarning("Could not start job for Watch: ", filter.WatchID)
@ -104,6 +106,20 @@ func (web *Web) addCronJobIfCronFilter(filter *Filter, startup bool) {
web.cronWatch[filter.ID] = entryID
}
func (web *Web) addCronJitter(watchID WatchID, filter *Filter) {
durations, err := getJittersFromScheduleString(filter.Var1)
if err != nil {
log.Println("Could not parse Schedule string:", filter.Var1)
return
}
for _, duration := range durations {
log.Println("Delaying by:", duration)
time.Sleep(duration)
}
TriggerSchedule(filter.WatchID, web, &filter.ID)
}
// validateProxyURL calls url.Parse with the proxy.url, if there is an error, it's added to startupWarnings
func (web *Web) validateProxyURL() {
if viper.IsSet("proxy.url") {