From 7833dcfab2fc4e2412b5be66e35126b85d1eeace Mon Sep 17 00:00:00 2001 From: Luke Gehorsam Date: Tue, 19 Sep 2023 14:52:06 -0400 Subject: [PATCH] fix calculation for future tournaments --- CHANGELOG.md | 4 ++++ server/core_tournament.go | 27 +++++++++++++++------------ server/core_tournament_test.go | 15 ++++++++------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1b466d731..106aded1d3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr ## [Unreleased] +### Fixed +- Fixes calculation of leaderboard and tournament times for rare types of CRON expressions that don't execute at a fixed interval. +- Improved how start and end times are calculated for tournaments occuring in the future. + ### [3.17.1] - 2023-08-23 ### Added - Add Satori `recompute` optional input parameter to relevant operations. diff --git a/server/core_tournament.go b/server/core_tournament.go index e627c8a092..b23dc9a671 100644 --- a/server/core_tournament.go +++ b/server/core_tournament.go @@ -731,23 +731,26 @@ func TournamentRecordsHaystack(ctx context.Context, logger *zap.Logger, db *sql. func calculateTournamentDeadlines(startTime, endTime, duration int64, resetSchedule *cronexpr.Expression, t time.Time) (int64, int64, int64) { tUnix := t.UTC().Unix() if resetSchedule != nil { - if tUnix < startTime { - // if startTime is in the future, always use startTime - t = time.Unix(startTime, 0).UTC() - tUnix = t.UTC().Unix() - } - var startActiveUnix int64 - // check if we are landing squarely on the reset schedule - if resetSchedule.Next(t.Add(-1*time.Second)) == t { - startActiveUnix = tUnix + + if tUnix < startTime { + // the supplied time is behind the start time + startActiveUnix = resetSchedule.Next(time.Unix(startTime, 0).UTC()).UTC().Unix() } else { - // otherwise assume the supplied time is ahead of the reset schedule. - startActiveUnix = resetSchedule.Last(t).UTC().Unix() + // check if we are landing squarely on the reset schedule + landsOnSched := resetSchedule.Next(t.Add(-1*time.Second)) == t + if landsOnSched { + startActiveUnix = tUnix + } else { + startActiveUnix = resetSchedule.Last(t).UTC().Unix() + } } + // endActiveUnix is when the current iteration ends. endActiveUnix := startActiveUnix + duration - expiryUnix := resetSchedule.Next(t).UTC().Unix() + // expiryUnix represent the start of the next schedule, i.e., when the next iteration begins. It's when the current records "expire". + expiryUnix := resetSchedule.Next(time.Unix(startActiveUnix, 0).UTC()).UTC().Unix() + if endActiveUnix > expiryUnix { // Cap the end active to the same time as the expiry. endActiveUnix = expiryUnix diff --git a/server/core_tournament_test.go b/server/core_tournament_test.go index db11d20c34..e2f1512161 100644 --- a/server/core_tournament_test.go +++ b/server/core_tournament_test.go @@ -97,15 +97,16 @@ func TestTournamentNowIsBeforeStart(t *testing.T) { t.Fatal("Invalid cron schedule", err) return } + var now int64 = 1692003600 // 14 August 2023, 9:00:00 var startTime int64 = 1693558800 // 1 September 2023, 9:00:00 - var duration int64 = 604800 * 1 // 1 week + var duration int64 = 604800 * 4 // 4 Weeks + nowUnix := time.Unix(now, 0).UTC() - startActiveUnix, endActiveUnix, expiryTime := calculateTournamentDeadlines(startTime, 0, duration, sched, nowUnix) - // September 14, 2023, 9:00:00 + startActiveUnix, endActiveUnix, _ := calculateTournamentDeadlines(startTime, 0, duration, sched, nowUnix) + + // 14 September 2023, 9:00:00 require.Equal(t, int64(1694682000), startActiveUnix, "Start active times should be equal.") - // September 21, 2023, 9:00:00 - require.Equal(t, int64(1695286800), endActiveUnix, "End active times should be equal.") - // October 14, 2023 9:00:00 - require.Equal(t, int64(1697274000), expiryTime, "Next reset times should be equal.") + // 12 October 2023, 9:00:00 + require.Equal(t, int64(1697101200), endActiveUnix, "End active times should be equal.") }