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

Skip to content

Commit 9807248

Browse files
committed
feat: add activity bumping to template scheduling
1 parent e436083 commit 9807248

File tree

18 files changed

+302
-41
lines changed

18 files changed

+302
-41
lines changed

coderd/database/dbauthz/dbauthz.go

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

2340+
func (q *querier) UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) error {
2341+
fetch := func(ctx context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) (database.Template, error) {
2342+
return q.db.GetTemplateByID(ctx, arg.TemplateID)
2343+
}
2344+
2345+
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateTemplateWorkspacesLastUsedAt)(ctx, arg)
2346+
}
2347+
23402348
// UpdateUserDeletedByID
23412349
// Deprecated: Delete this function in favor of 'SoftDeleteUserByID'. Deletes are
23422350
// irreversible.
@@ -2615,12 +2623,12 @@ func (q *querier) UpdateWorkspaceTTL(ctx context.Context, arg database.UpdateWor
26152623
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceTTL)(ctx, arg)
26162624
}
26172625

2618-
func (q *querier) UpdateWorkspacesDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) error {
2619-
fetch := func(ctx context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) (database.Template, error) {
2626+
func (q *querier) UpdateWorkspacesLockedDeletingAtByTemplateID(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
2627+
fetch := func(ctx context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) (database.Template, error) {
26202628
return q.db.GetTemplateByID(ctx, arg.TemplateID)
26212629
}
26222630

2623-
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesDeletingAtByTemplateID)(ctx, arg)
2631+
return fetchAndExec(q.log, q.auth, rbac.ActionUpdate, fetch, q.db.UpdateWorkspacesLockedDeletingAtByTemplateID)(ctx, arg)
26242632
}
26252633

26262634
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
@@ -4769,6 +4769,26 @@ func (q *FakeQuerier) UpdateTemplateVersionGitAuthProvidersByJobID(_ context.Con
47694769
return sql.ErrNoRows
47704770
}
47714771

4772+
func (q *FakeQuerier) UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg database.UpdateTemplateWorkspacesLastUsedAtParams) error {
4773+
err := validateDatabaseType(arg)
4774+
if err != nil {
4775+
return err
4776+
}
4777+
4778+
q.mutex.Lock()
4779+
defer q.mutex.Unlock()
4780+
4781+
for i, ws := range q.workspaces {
4782+
if ws.TemplateID != arg.TemplateID {
4783+
continue
4784+
}
4785+
ws.LastUsedAt = arg.LastUsedAt
4786+
q.workspaces[i] = ws
4787+
}
4788+
4789+
return nil
4790+
}
4791+
47724792
func (q *FakeQuerier) UpdateUserDeletedByID(_ context.Context, params database.UpdateUserDeletedByIDParams) error {
47734793
if err := validateDatabaseType(params); err != nil {
47744794
return err
@@ -5349,7 +5369,7 @@ func (q *FakeQuerier) UpdateWorkspaceTTL(_ context.Context, arg database.UpdateW
53495369
return sql.ErrNoRows
53505370
}
53515371

5352-
func (q *FakeQuerier) UpdateWorkspacesDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesDeletingAtByTemplateIDParams) error {
5372+
func (q *FakeQuerier) UpdateWorkspacesLockedDeletingAtByTemplateID(_ context.Context, arg database.UpdateWorkspacesLockedDeletingAtByTemplateIDParams) error {
53535373
q.mutex.Lock()
53545374
defer q.mutex.Unlock()
53555375

@@ -5359,9 +5379,21 @@ func (q *FakeQuerier) UpdateWorkspacesDeletingAtByTemplateID(_ context.Context,
53595379
}
53605380

53615381
for i, ws := range q.workspaces {
5382+
if ws.TemplateID != arg.TemplateID {
5383+
continue
5384+
}
5385+
53625386
if ws.LockedAt.Time.IsZero() {
53635387
continue
53645388
}
5389+
5390+
if !arg.LockedAt.IsZero() {
5391+
ws.LockedAt = sql.NullTime{
5392+
Valid: true,
5393+
Time: arg.LockedAt,
5394+
}
5395+
}
5396+
53655397
deletingAt := sql.NullTime{
53665398
Valid: arg.LockedTtlMs > 0,
53675399
}

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
@@ -104,6 +104,18 @@ type TemplateScheduleOptions struct {
104104
// LockedTTL dictates the duration after which locked workspaces will be
105105
// permanently deleted.
106106
LockedTTL time.Duration `json:"locked_ttl"`
107+
// UpdateWorkspaceLastUsedAt updates the template's workspaces'
108+
// last_used_at field. This is useful for preventing updates to the
109+
// templates inactivity_ttl immediately triggering a lock action against
110+
// workspaces whose last_used_at field violates the new template
111+
// inactivity_ttl threshold.
112+
UpdateWorkspaceLastUsedAt bool `json:"update_workspace_last_used_at"`
113+
// UpdateWorkspaceLockedAt updates the template's workspaces'
114+
// locked_at field. This is useful for preventing updates to the
115+
// templates locked_ttl immediately triggering a delete action against
116+
// workspaces whose locked_at field violates the new template locked_ttl
117+
// threshold.
118+
UpdateWorkspaceLockedAt bool `json:"update_workspace_locked_at"`
107119
}
108120

109121
// 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)