diff --git a/README.md b/README.md index b882ebb..a7294ac 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ level of precision is better left to other tools. * `interval`: *Optional.* The interval on which to report new versions. Valid values: `60s`, `90m`, `1h`. +* `skew`: *Optional.* A maximum bound of time by which to skew the trigger + time. Valid values: `60s`, `90m`, `1h`. Must be used with `interval`. + * `location`: *Optional. Default `UTC`.* The [location](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) in which to interpret `start`, `stop`, and `days`. @@ -95,6 +98,25 @@ jobs: config: # ... ``` +### Periodic trigger with some skewing + +```yaml +resources: +- name: 5-ish-min + type: time + source: + interval: 5m + skew: 1m + +jobs: +- name: something-every-4-to-6m + plan: + - get: 5-ish-min + trigger: true + - task: something + config: # ... +``` + ### Trigger once within time range ```yaml diff --git a/check/main.go b/check/main.go index 4f5ecac..5e9ad36 100644 --- a/check/main.go +++ b/check/main.go @@ -34,6 +34,7 @@ func main() { Start: request.Source.Start, Stop: request.Source.Stop, Interval: request.Source.Interval, + Skew: request.Source.Skew, Days: request.Source.Days, } diff --git a/lord/time_lord.go b/lord/time_lord.go index 706c853..4d210ec 100644 --- a/lord/time_lord.go +++ b/lord/time_lord.go @@ -1,6 +1,7 @@ package lord import ( + "math/rand" "time" "github.com/concourse/time-resource/models" @@ -12,6 +13,7 @@ type TimeLord struct { Start *models.TimeOfDay Stop *models.TimeOfDay Interval *models.Interval + Skew *models.Interval Days []models.Weekday } @@ -29,7 +31,11 @@ func (tl TimeLord) Check(now time.Time) bool { } if tl.Interval != nil { - if now.Sub(tl.PreviousTime) >= time.Duration(*tl.Interval) { + skew := time.Duration(0) + if tl.Skew != nil { + skew = time.Duration(rand.Intn(int(time.Duration(*tl.Interval).Seconds()))) + } + if now.Sub(tl.PreviousTime)+skew >= time.Duration(*tl.Interval) { return true } } else { diff --git a/models/models.go b/models/models.go index 7c95835..0ae71f7 100644 --- a/models/models.go +++ b/models/models.go @@ -40,6 +40,7 @@ type CheckResponse []Version type Source struct { Interval *Interval `json:"interval"` + Skew *Interval `json:"skew"` Start *TimeOfDay `json:"start"` Stop *TimeOfDay `json:"stop"` Days []Weekday `json:"days"` @@ -51,6 +52,10 @@ func (source Source) Validate() error { return errors.New("must configure either 'interval' or 'start' and 'stop'") } + if source.Interval == nil && source.Skew != nil { + return errors.New("must configure either 'interval' if 'skew' is used") + } + if source.Start != nil && source.Stop == nil { return errors.New("must configure 'stop' if 'start' is set") }