Sleep schedule: store 'next check' timestamp in UTC

SQLite doesn't parse the timezone info, so timestamps should always be in
UTC.
This commit is contained in:
Sybren A. Stüvel 2022-07-18 19:30:17 +02:00
parent 3baac0a2d8
commit 83467e4c60
4 changed files with 22 additions and 6 deletions

@ -63,6 +63,11 @@ func (db *DB) SetWorkerSleepSchedule(ctx context.Context, workerUUID string, sch
schedule.WorkerID = worker.ID
schedule.Worker = worker
// Only store timestamps in UTC.
if schedule.NextCheck.Location() != time.UTC {
schedule.NextCheck = schedule.NextCheck.UTC()
}
tx := db.gormDB.WithContext(ctx).
Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "worker_id"}},
@ -73,6 +78,11 @@ func (db *DB) SetWorkerSleepSchedule(ctx context.Context, workerUUID string, sch
}
func (db *DB) SetWorkerSleepScheduleNextCheck(ctx context.Context, schedule *SleepSchedule) error {
// Only store timestamps in UTC.
if schedule.NextCheck.Location() != time.UTC {
schedule.NextCheck = schedule.NextCheck.UTC()
}
tx := db.gormDB.WithContext(ctx).
Select("next_check").
Updates(schedule)
@ -92,10 +102,12 @@ func (db *DB) FetchSleepScheduleWorker(ctx context.Context, schedule *SleepSched
// FetchSleepSchedulesToCheck returns the sleep schedules that are due for a check.
func (db *DB) FetchSleepSchedulesToCheck(ctx context.Context) ([]*SleepSchedule, error) {
log.Trace().Msg("fetching sleep schedules that need checking")
now := db.gormDB.NowFunc()
log.Debug().
Str("timeout", now.String()).
Msg("fetching sleep schedules that need checking")
schedules := []*SleepSchedule{}
tx := db.gormDB.WithContext(ctx).
Model(&SleepSchedule{}).

@ -243,7 +243,7 @@ func TestFetchSleepSchedulesToCheck(t *testing.T) {
ctx, finish, db := persistenceTestFixtures(t, 1*time.Second)
defer finish()
mockedNow := mustParseTime("2022-06-07T11:14:47+02:00")
mockedNow := mustParseTime("2022-06-07T11:14:47+02:00").UTC()
mockedPast := mockedNow.Add(-10 * time.Second)
mockedFuture := mockedNow.Add(10 * time.Second)

@ -69,7 +69,7 @@ func calculateNextCheck(now time.Time, schedule *persistence.SleepSchedule) time
nextChecks := []time.Time{
// Always check at the end of the day.
calcNext(persistence.TimeOfDay{Hour: 24, Minute: 0}),
endOfDay(now),
}
// No start time means "start of the day", which is already covered by
@ -96,3 +96,8 @@ func earliestTime(timestamps []time.Time) time.Time {
}
return earliest
}
// endOfDay returns the next midnight at UTC.
func endOfDay(now time.Time) time.Time {
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).AddDate(0, 0, 1)
}

@ -232,12 +232,11 @@ type TestMocks struct {
func (m *TestMocks) todayAt(hour, minute int) time.Time {
now := m.clock.Now()
return time.Date(now.Year(), now.Month(), now.Day(), hour, minute, 0, 0, now.Location())
}
// endOfDay returns midnight of the day after whatever the mocked clock's "now" is set to.
func (m *TestMocks) endOfDay() time.Time {
now := m.clock.Now()
now := m.clock.Now().UTC()
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).AddDate(0, 0, 1)
}