feat!: bump workspace activity by 1 hour (#10704)

Marked as a breaking change as the previous activity bump was always the TTL duration of the workspace/template.

This change is more cost conservative, only bumping by 1 hour for workspace activity. To accommodate wrap around, eg bumping a workspace into the next autostart, the deadline is bumped by the TTL if the workspace crosses the autostart threshold.

This is a niche case that is likely caused by an idle terminal making a workspace survive through a night. The next morning, the workspace will get activity bumped the default TTL on the autostart, being similar to as if the workspace was autostarted again.

In practice, a good way to avoid this is to set a max_deadline of <24hrs to avoid wrap around entirely.
This commit is contained in:
Steven Masley
2023-11-15 09:42:27 -06:00
committed by GitHub
parent 6085b92fae
commit 290180b104
12 changed files with 235 additions and 88 deletions

View File

@ -30,7 +30,7 @@ func TestWorkspaceActivityBump(t *testing.T) {
// max_deadline on the build directly in the database.
setupActivityTest := func(t *testing.T, deadline ...time.Duration) (client *codersdk.Client, workspace codersdk.Workspace, assertBumped func(want bool)) {
t.Helper()
const ttl = time.Minute
const ttl = time.Hour
maxTTL := time.Duration(0)
if len(deadline) > 0 {
maxTTL = deadline[0]
@ -71,28 +71,29 @@ func TestWorkspaceActivityBump(t *testing.T) {
})
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
var maxDeadline time.Time
// Update the max deadline.
if maxTTL != 0 {
dbBuild, err := db.GetWorkspaceBuildByID(ctx, workspace.LatestBuild.ID)
require.NoError(t, err)
err = db.UpdateWorkspaceBuildDeadlineByID(ctx, database.UpdateWorkspaceBuildDeadlineByIDParams{
ID: workspace.LatestBuild.ID,
UpdatedAt: dbtime.Now(),
Deadline: dbBuild.Deadline,
MaxDeadline: dbtime.Now().Add(maxTTL),
})
require.NoError(t, err)
maxDeadline = dbtime.Now().Add(maxTTL)
}
err := db.UpdateWorkspaceBuildDeadlineByID(ctx, database.UpdateWorkspaceBuildDeadlineByIDParams{
ID: workspace.LatestBuild.ID,
UpdatedAt: dbtime.Now(),
// Make the deadline really close so it needs to be bumped immediately.
Deadline: dbtime.Now().Add(time.Minute),
MaxDeadline: maxDeadline,
})
require.NoError(t, err)
_ = agenttest.New(t, client.URL, agentToken)
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
// Sanity-check that deadline is near.
workspace, err := client.Workspace(ctx, workspace.ID)
// Sanity-check that deadline is nearing requiring a bump.
workspace, err = client.Workspace(ctx, workspace.ID)
require.NoError(t, err)
require.WithinDuration(t,
time.Now().Add(time.Duration(ttlMillis)*time.Millisecond),
time.Now().Add(time.Minute),
workspace.LatestBuild.Deadline.Time,
testutil.WaitMedium,
)
@ -133,7 +134,7 @@ func TestWorkspaceActivityBump(t *testing.T) {
workspace, err = client.Workspace(ctx, workspace.ID)
require.NoError(t, err)
updatedAfter = dbtime.Now()
if workspace.LatestBuild.Deadline.Time == firstDeadline {
if workspace.LatestBuild.Deadline.Time.Equal(firstDeadline) {
updatedAfter = time.Now()
return false
}
@ -151,6 +152,13 @@ func TestWorkspaceActivityBump(t *testing.T) {
require.LessOrEqual(t, workspace.LatestBuild.Deadline.Time, workspace.LatestBuild.MaxDeadline.Time)
return
}
now := dbtime.Now()
zone, offset := time.Now().Zone()
t.Logf("[Zone=%s %d] originDeadline: %s, deadline: %s, now %s, (now-deadline)=%s",
zone, offset,
firstDeadline, workspace.LatestBuild.Deadline.Time, now,
now.Sub(workspace.LatestBuild.Deadline.Time),
)
require.WithinDuration(t, dbtime.Now().Add(ttl), workspace.LatestBuild.Deadline.Time, testutil.WaitShort)
}
}
@ -192,9 +200,9 @@ func TestWorkspaceActivityBump(t *testing.T) {
t.Run("NotExceedMaxDeadline", func(t *testing.T) {
t.Parallel()
// Set the max deadline to be in 61 seconds. We bump by 1 minute, so we
// Set the max deadline to be in 30min. We bump by 1 hour, so we
// should expect the deadline to match the max deadline exactly.
client, workspace, assertBumped := setupActivityTest(t, 61*time.Second)
client, workspace, assertBumped := setupActivityTest(t, time.Minute*30)
// Bump by dialing the workspace and sending traffic.
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)