Skip to content

Commit

Permalink
Merge pull request #54 from owenfarrell/offset
Browse files Browse the repository at this point in the history
Ensure even distribution of versions across interval/range
  • Loading branch information
vito authored Aug 21, 2020
2 parents 23cbebb + 3153e0d commit 2bfa77c
Show file tree
Hide file tree
Showing 4 changed files with 455 additions and 5 deletions.
10 changes: 5 additions & 5 deletions lord/time_lord.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type TimeLord struct {

func (tl TimeLord) Check(now time.Time) bool {

start, stop := tl.latestRangeBefore(now)
start, stop := tl.LatestRangeBefore(now)

if !tl.daysMatch(now) {
return false
Expand Down Expand Up @@ -54,7 +54,7 @@ func (tl TimeLord) Latest(reference time.Time) time.Time {
refInLoc = refInLoc.AddDate(0, 0, -1)
}

start, stop := tl.latestRangeBefore(refInLoc)
start, stop := tl.LatestRangeBefore(refInLoc)

if tl.PreviousTime.IsZero() && !reference.Before(stop) {
return time.Time{}
Expand Down Expand Up @@ -85,7 +85,7 @@ func (tl TimeLord) List(reference time.Time) []time.Time {
if tl.Interval == nil {

if start.IsZero() {
refRangeStart, refRangeEnd := tl.latestRangeBefore(reference)
refRangeStart, refRangeEnd := tl.LatestRangeBefore(reference)
if !reference.Before(refRangeEnd) {
return versions
}
Expand Down Expand Up @@ -122,7 +122,7 @@ func (tl TimeLord) List(reference time.Time) []time.Time {
var dailyStart, dailyEnd time.Time
for dailyInterval := start; !dailyStart.After(reference); dailyInterval = dailyInterval.AddDate(0, 0, 1) {
if tl.daysMatch(dailyInterval) {
dailyStart, dailyEnd = tl.latestRangeBefore(dailyInterval)
dailyStart, dailyEnd = tl.LatestRangeBefore(dailyInterval)
if dailyStart.After(reference) {
break
}
Expand All @@ -148,7 +148,7 @@ func (tl TimeLord) daysMatch(now time.Time) bool {
return false
}

func (tl TimeLord) latestRangeBefore(reference time.Time) (time.Time, time.Time) {
func (tl TimeLord) LatestRangeBefore(reference time.Time) (time.Time, time.Time) {

tlStart := DEFAULT_TIME_OF_DAY
if tl.Start != nil {
Expand Down
48 changes: 48 additions & 0 deletions offset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package resource

import (
"fmt"
"hash/fnv"
"math"
"os"
"time"

"github.com/concourse/time-resource/lord"
)

const BUILD_TEAM_NAME = "BUILD_TEAM_NAME"
const BUILD_PIPELINE_NAME = "BUILD_PIPELINE_NAME"
const offsetHashFormat = "%s/%s"

const maxHashValue = int64(math.MaxUint32)

var msPerMinute = time.Minute.Milliseconds()

func Offset(tl lord.TimeLord, reference time.Time) time.Time {
str := fmt.Sprintf(offsetHashFormat, os.Getenv(BUILD_TEAM_NAME), os.Getenv(BUILD_PIPELINE_NAME))
hasher := fnv.New32a()
if _, err := hasher.Write([]byte(str)); err != nil {
fmt.Fprintln(os.Stderr, "hash error:", err.Error())
os.Exit(1)
}
hash := int64(hasher.Sum32())

start, stop := tl.LatestRangeBefore(reference)
rangeDuration := stop.Sub(start)

if tl.Interval != nil {
if intervalDuration := time.Duration(*tl.Interval); intervalDuration < rangeDuration {
rangeDuration = intervalDuration
start = reference.Truncate(rangeDuration)
}
}

if rangeDuration <= time.Minute {
return start
}

hashPerMinute := maxHashValue / (rangeDuration.Milliseconds() / msPerMinute)
offsetDuration := time.Duration(hash/hashPerMinute) * time.Minute

return start.Add(offsetDuration)
}
Loading

0 comments on commit 2bfa77c

Please sign in to comment.