Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45e923e

Browse files
committed
feat: add activity bumping to template scheduling
1 parent 2a04d15 commit 45e923e

File tree

20 files changed

+522
-87
lines changed

20 files changed

+522
-87
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,14 @@ func (q *querier) UpdateTemplateVersionGitAuthProvidersByJobID(ctx context.Conte
23852385
return q.db.UpdateTemplateVersionGitAuthProvidersByJobID(ctx, arg)
23862386
}
23872387

2388+
func (q *querier) UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) error {
2389+
fetch := func(ctx context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) (database.Template, error) {
2390+
return q.db.GetTemplateByID(ctx, arg.TemplateID)
2391+
}
2392+
2393+
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateTemplateWorkspacesLastUsedAt)(ctx, arg)
2394+
}
2395+
23882396
// UpdateUserDeletedByID
23892397
// Deprecated: Delete this function in favor of 'SoftDeleteUserByID'. Deletes are
23902398
// irreversible.
@@ -2663,12 +2671,12 @@ func (q *querier) UpdateWorkspaceTTL(ctx context.Context, arg database.UpdateWor
26632671
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceTTL)(ctx, arg)
26642672
}
26652673

2666-
func (q *querier) UpdateWorkspacesDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) error {
2667-
fetch := func(ctx context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) (database.Template, error) {
2674+
func (q *querier) UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
2675+
fetch := func(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) (database.Template, error) {
26682676
return q.db.GetTemplateByID(ctx, arg.TemplateID)
26692677
}
26702678

2671-
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesDeletingAtByTemplateID)(ctx, arg)
2679+
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesLockedDeletingAtByTemplateID)(ctx, arg)
26722680
}
26732681

26742682
func (q *querier) UpsertAppSecurityKey(ctx context.Context, data string) error {

coderd/database/dbfake/dbfake.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5199,6 +5199,26 @@ func (q *FakeQuerier) UpdateTemplateVersionGitAuthProvidersByJobID(_ context.Con
51995199
return sql.ErrNoRows
52005200
}
52015201

5202+
func (q *FakeQuerier) UpdateTemplateWorkspacesLastUsedAt(_ context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) error {
5203+
err := validateDatabaseType(arg)
5204+
if err != nil {
5205+
return err
5206+
}
5207+
5208+
q.mutex.Lock()
5209+
defer q.mutex.Unlock()
5210+
5211+
for i, ws := range q.workspaces {
5212+
if ws.TemplateID != arg.TemplateID {
5213+
continue
5214+
}
5215+
ws.LastUsedAt = arg.LastUsedAt
5216+
q.workspaces[i] = ws
5217+
}
5218+
5219+
return nil
5220+
}
5221+
52025222
func (q *FakeQuerier) UpdateUserDeletedByID(_ context.Context, params database.UpdateUserDeletedByIDParams) error {
52035223
if err := validateDatabaseType(params); err != nil {
52045224
return err
@@ -5796,7 +5816,7 @@ func (q *FakeQuerier) UpdateWorkspaceTTL(_ context.Context, arg database.UpdateW
57965816
return sql.ErrNoRows
57975817
}
57985818

5799-
func (q *FakeQuerier) UpdateWorkspacesDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) error {
5819+
func (q *FakeQuerier) UpdateWorkspacesLockedDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
58005820
q.mutex.Lock()
58015821
defer q.mutex.Unlock()
58025822

@@ -5806,9 +5826,21 @@ func (q *FakeQuerier) UpdateWorkspacesDeletingAtByTemplateID(_ context.Context,
58065826
}
58075827

58085828
for i, ws := range q.workspaces {
5829+
if ws.TemplateID != arg.TemplateID {
5830+
continue
5831+
}
5832+
58095833
if ws.LockedAt.Time.IsZero() {
58105834
continue
58115835
}
5836+
5837+
if !arg.LockedAt.IsZero() {
5838+
ws.LockedAt = sql.NullTime{
5839+
Valid: true,
5840+
Time: arg.LockedAt,
5841+
}
5842+
}
5843+
58125844
deletingAt := sql.NullTime{
58135845
Valid: arg.LockedTtlMs > 0,
58145846
}

coderd/database/dbmetrics/dbmetrics.go

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

coderd/database/dbmock/dbmock.go

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

coderd/database/querier.go

Lines changed: 2 additions & 1 deletion
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: 32 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaces.sql

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,23 @@ AND
501501
workspaces.id = $1
502502
RETURNING workspaces.*;
503503

504-
-- name: UpdateWorkspacesDeletingAtByTemplateID :exec
505-
UPDATE
506-
workspaces
504+
-- name: UpdateWorkspacesLockedDeletingAtByTemplateID :exec
505+
UPDATE workspaces
507506
SET
508-
deleting_at = CASE WHEN @locked_ttl_ms::bigint = 0 THEN NULL ELSE locked_at + interval '1 milliseconds' * @locked_ttl_ms::bigint END
507+
deleting_at = CASE
508+
WHEN @locked_ttl_ms::bigint = 0 THEN NULL
509+
WHEN @locked_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN (@locked_at::timestamptz) + interval '1 milliseconds' * @locked_ttl_ms::bigint
510+
ELSE locked_at + interval '1 milliseconds' * @locked_ttl_ms::bigint
511+
END,
512+
locked_at = CASE WHEN @locked_at::timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN @locked_at::timestamptz ELSE locked_at END
509513
WHERE
510-
template_id = @template_id
514+
template_id = @template_id
511515
AND
512-
locked_at IS NOT NULL;
516+
locked_at IS NOT NULL;
517+
518+
-- name: UpdateTemplateWorkspacesLastUsedAt :exec
519+
UPDATE workspaces
520+
SET
521+
last_used_at = @last_used_at::timestamptz
522+
WHERE
523+
template_id = @template_id;

coderd/schedule/template.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ type TemplateScheduleOptions struct {
105105
// LockedTTL dictates the duration after which locked workspaces will be
106106
// permanently deleted.
107107
LockedTTL time.Duration `json:"locked_ttl"`
108+
// UpdateWorkspaceLastUsedAt updates the template's workspaces'
109+
// last_used_at field. This is useful for preventing updates to the
110+
// templates inactivity_ttl immediately triggering a lock action against
111+
// workspaces whose last_used_at field violates the new template
112+
// inactivity_ttl threshold.
113+
UpdateWorkspaceLastUsedAt bool `json:"update_workspace_last_used_at"`
114+
// UpdateWorkspaceLockedAt updates the template's workspaces'
115+
// locked_at field. This is useful for preventing updates to the
116+
// templates locked_ttl immediately triggering a delete action against
117+
// workspaces whose locked_at field violates the new template locked_ttl
118+
// threshold.
119+
UpdateWorkspaceLockedAt bool `json:"update_workspace_locked_at"`
108120
}
109121

110122
// TemplateScheduleStore provides an interface for retrieving template

coderd/templates.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,11 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
622622
DaysOfWeek: restartRequirementDaysOfWeekParsed,
623623
Weeks: req.RestartRequirement.Weeks,
624624
},
625-
FailureTTL: failureTTL,
626-
InactivityTTL: inactivityTTL,
627-
LockedTTL: lockedTTL,
625+
FailureTTL: failureTTL,
626+
InactivityTTL: inactivityTTL,
627+
LockedTTL: lockedTTL,
628+
UpdateWorkspaceLastUsedAt: req.UpdateWorkspaceLastUsedAt,
629+
UpdateWorkspaceLockedAt: req.UpdateWorkspaceLockedAt,
628630
})
629631
if err != nil {
630632
return xerrors.Errorf("set template schedule options: %w", err)

codersdk/templates.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ type UpdateTemplateMeta struct {
192192
FailureTTLMillis int64 `json:"failure_ttl_ms,omitempty"`
193193
InactivityTTLMillis int64 `json:"inactivity_ttl_ms,omitempty"`
194194
LockedTTLMillis int64 `json:"locked_ttl_ms,omitempty"`
195+
// UpdateWorkspaceLastUsedAt updates the last_used_at field of workspaces
196+
// spawned from the template. This is useful for preventing workspaces being
197+
// immediately locked when updating the inactivity_ttl field to a new, shorter
198+
// value.
199+
UpdateWorkspaceLastUsedAt bool `json:"update_workspace_last_used_at"`
200+
// UpdateWorkspaceLockedAt updates the locked_at field of workspaces spawned
201+
// from the template. This is useful for preventing locked workspaces being immediately
202+
// deleted when updating the locked_ttl field to a new, shorter value.
203+
UpdateWorkspaceLockedAt bool `json:"update_workspace_locked_at"`
195204
}
196205

197206
type TemplateExample struct {

0 commit comments

Comments
 (0)