Skip to content

Commit c36b27d

Browse files
committed
feat: write query to adjust ttl bump
1 parent 141cba9 commit c36b27d

File tree

5 files changed

+43
-25
lines changed

5 files changed

+43
-25
lines changed

coderd/autobuild/lifecycle_executor.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,26 +357,36 @@ func isEligibleForAutostart(ws database.Workspace, build database.WorkspaceBuild
357357
return false
358358
}
359359

360-
sched, err := cron.Weekly(ws.AutostartSchedule.String)
361-
if err != nil {
360+
nextTransition, allowed := NextAutostartSchedule(build.CreatedAt, ws.AutostartSchedule.String, templateSchedule)
361+
if !allowed {
362362
return false
363363
}
364+
365+
// Must use '.Before' vs '.After' so equal times are considered "valid for autostart".
366+
return !currentTick.Before(nextTransition)
367+
}
368+
369+
// NextAutostartSchedule takes the workspace and template schedule and returns the next autostart schedule
370+
// after "at". The boolean returned is if the autostart should be allowed to start based on the template
371+
// schedule.
372+
func NextAutostartSchedule(at time.Time, wsSchedule string, templateSchedule schedule.TemplateScheduleOptions) (time.Time, bool) {
373+
sched, err := cron.Weekly(wsSchedule)
374+
if err != nil {
375+
return time.Time{}, false
376+
}
377+
364378
// Round down to the nearest minute, as this is the finest granularity cron supports.
365379
// Truncate is probably not necessary here, but doing it anyway to be sure.
366-
nextTransition := sched.Next(build.CreatedAt).Truncate(time.Minute)
380+
nextTransition := sched.Next(at).Truncate(time.Minute)
367381

368382
// The nextTransition is when the auto start should kick off. If it lands on a
369383
// forbidden day, do not allow the auto start. We use the time location of the
370384
// schedule to determine the weekday. So if "Saturday" is disallowed, the
371385
// definition of "Saturday" depends on the location of the schedule.
372386
zonedTransition := nextTransition.In(sched.Location())
373387
allowed := templateSchedule.AutostartRequirement.DaysMap()[zonedTransition.Weekday()]
374-
if !allowed {
375-
return false
376-
}
377388

378-
// Must used '.Before' vs '.After' so equal times are considered "valid for autostart".
379-
return !currentTick.Before(nextTransition)
389+
return zonedTransition, allowed
380390
}
381391

382392
// isEligibleForAutostart returns true if the workspace should be autostopped.

coderd/database/querier.go

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 5 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/activitybump.sql

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
-- We bump by the original TTL to prevent counter-intuitive behavior
2-
-- as the TTL wraps. For example, if I set the TTL to 12 hours, sign off
3-
-- work at midnight, come back at 10am, I would want another full day
4-
-- of uptime.
51
-- name: ActivityBumpWorkspace :exec
62
WITH latest AS (
73
SELECT

coderd/workspaceagents.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"sync/atomic"
2020
"time"
2121

22+
"github.com/coder/coder/v2/coderd/autobuild"
23+
2224
"github.com/google/uuid"
2325
"github.com/sqlc-dev/pqtype"
2426
"golang.org/x/exp/maps"
@@ -1671,7 +1673,24 @@ func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Reques
16711673
)
16721674

16731675
if req.ConnectionCount > 0 {
1674-
activityBumpWorkspace(ctx, api.Logger.Named("activity_bump"), api.Database, workspace.ID, time.Time{})
1676+
var nextAutostart time.Time
1677+
if workspace.AutostartSchedule.String != "" {
1678+
templateSchedule, err := (*(api.TemplateScheduleStore.Load())).Get(ctx, api.Database, workspace.TemplateID)
1679+
// If the template schedule fails to load, just default to bumping without the next trasition and log it.
1680+
if err != nil {
1681+
api.Logger.Warn(ctx, "failed to load template schedule bumping activity",
1682+
slog.F("workspace_id", workspace.ID),
1683+
slog.F("template_id", workspace.TemplateID),
1684+
slog.Error(err),
1685+
)
1686+
} else {
1687+
next, allowed := autobuild.NextAutostartSchedule(time.Now(), workspace.AutostartSchedule.String, templateSchedule)
1688+
if allowed {
1689+
nextAutostart = next
1690+
}
1691+
}
1692+
}
1693+
activityBumpWorkspace(ctx, api.Logger.Named("activity_bump"), api.Database, workspace.ID, nextAutostart)
16751694
}
16761695

16771696
now := dbtime.Now()

0 commit comments

Comments
 (0)