@@ -6868,60 +6868,99 @@ func (q *FakeQuerier) GetWorkspacesAndAgentsByOwnerID(ctx context.Context, owner
68686868return q .GetAuthorizedWorkspacesAndAgentsByOwnerID (ctx ,ownerID ,nil )
68696869}
68706870
6871- func (q * FakeQuerier )GetWorkspacesEligibleForTransition (ctx context.Context ,now time.Time ) ([]database.WorkspaceTable ,error ) {
6871+ func (q * FakeQuerier )GetWorkspacesEligibleForTransition (ctx context.Context ,now time.Time ) ([]database.GetWorkspacesEligibleForTransitionRow ,error ) {
68726872q .mutex .RLock ()
68736873defer q .mutex .RUnlock ()
68746874
6875- workspaces := []database.WorkspaceTable {}
6875+ workspaces := []database.GetWorkspacesEligibleForTransitionRow {}
68766876for _ ,workspace := range q .workspaces {
68776877build ,err := q .getLatestWorkspaceBuildByWorkspaceIDNoLock (ctx ,workspace .ID )
68786878if err != nil {
6879- return nil ,err
6880- }
6881-
6882- if build .Transition == database .WorkspaceTransitionStart &&
6883- ! build .Deadline .IsZero ()&&
6884- build .Deadline .Before (now )&&
6885- ! workspace .DormantAt .Valid {
6886- workspaces = append (workspaces ,workspace )
6887- continue
6879+ return nil ,xerrors .Errorf ("get workspace build by ID: %w" ,err )
68886880}
68896881
6890- if build .Transition == database .WorkspaceTransitionStop &&
6891- workspace .AutostartSchedule .Valid &&
6892- ! workspace .DormantAt .Valid {
6893- workspaces = append (workspaces ,workspace )
6894- continue
6882+ user ,err := q .getUserByIDNoLock (workspace .OwnerID )
6883+ if err != nil {
6884+ return nil ,xerrors .Errorf ("get user by ID: %w" ,err )
68956885}
68966886
68976887job ,err := q .getProvisionerJobByIDNoLock (ctx ,build .JobID )
68986888if err != nil {
68996889return nil ,xerrors .Errorf ("get provisioner job by ID: %w" ,err )
69006890}
6901- if codersdk .ProvisionerJobStatus (job .JobStatus )== codersdk .ProvisionerJobFailed {
6902- workspaces = append (workspaces ,workspace )
6903- continue
6904- }
69056891
69066892template ,err := q .getTemplateByIDNoLock (ctx ,workspace .TemplateID )
69076893if err != nil {
69086894return nil ,xerrors .Errorf ("get template by ID: %w" ,err )
69096895}
6910- if ! workspace . DormantAt . Valid && template . TimeTilDormant > 0 {
6911- workspaces = append ( workspaces , workspace )
6896+
6897+ if workspace . Deleted {
69126898continue
69136899}
6914- if workspace .DormantAt .Valid && template .TimeTilDormantAutoDelete > 0 {
6915- workspaces = append (workspaces ,workspace )
6900+
6901+ if job .JobStatus != database .ProvisionerJobStatusFailed &&
6902+ ! workspace .DormantAt .Valid &&
6903+ build .Transition == database .WorkspaceTransitionStart &&
6904+ (user .Status == database .UserStatusSuspended || (! build .Deadline .IsZero ()&& build .Deadline .Before (now ))) {
6905+ workspaces = append (workspaces , database.GetWorkspacesEligibleForTransitionRow {
6906+ ID :workspace .ID ,
6907+ Name :workspace .Name ,
6908+ })
69166909continue
69176910}
69186911
6919- user ,err := q .getUserByIDNoLock (workspace .OwnerID )
6920- if err != nil {
6921- return nil ,xerrors .Errorf ("get user by ID: %w" ,err )
6912+ if user .Status == database .UserStatusActive &&
6913+ job .JobStatus != database .ProvisionerJobStatusFailed &&
6914+ build .Transition == database .WorkspaceTransitionStop &&
6915+ workspace .AutostartSchedule .Valid {
6916+ workspaces = append (workspaces , database.GetWorkspacesEligibleForTransitionRow {
6917+ ID :workspace .ID ,
6918+ Name :workspace .Name ,
6919+ })
6920+ continue
69226921}
6923- if user .Status == database .UserStatusSuspended && build .Transition == database .WorkspaceTransitionStart {
6924- workspaces = append (workspaces ,workspace )
6922+
6923+ if ! workspace .DormantAt .Valid &&
6924+ template .TimeTilDormant > 0 &&
6925+ now .Sub (workspace .LastUsedAt )> time .Duration (template .TimeTilDormant ) {
6926+ workspaces = append (workspaces , database.GetWorkspacesEligibleForTransitionRow {
6927+ ID :workspace .ID ,
6928+ Name :workspace .Name ,
6929+ })
6930+ continue
6931+ }
6932+
6933+ if workspace .DormantAt .Valid &&
6934+ workspace .DeletingAt .Valid &&
6935+ workspace .DeletingAt .Time .Before (now )&&
6936+ template .TimeTilDormantAutoDelete > 0 {
6937+ if build .Transition == database .WorkspaceTransitionDelete &&
6938+ job .JobStatus == database .ProvisionerJobStatusFailed {
6939+ if job .CanceledAt .Valid && now .Sub (job .CanceledAt .Time )<= 24 * time .Hour {
6940+ continue
6941+ }
6942+
6943+ if job .CompletedAt .Valid && now .Sub (job .CompletedAt .Time )<= 24 * time .Hour {
6944+ continue
6945+ }
6946+ }
6947+
6948+ workspaces = append (workspaces , database.GetWorkspacesEligibleForTransitionRow {
6949+ ID :workspace .ID ,
6950+ Name :workspace .Name ,
6951+ })
6952+ continue
6953+ }
6954+
6955+ if template .FailureTTL > 0 &&
6956+ build .Transition == database .WorkspaceTransitionStart &&
6957+ job .JobStatus == database .ProvisionerJobStatusFailed &&
6958+ job .CompletedAt .Valid &&
6959+ now .Sub (job .CompletedAt .Time )> time .Duration (template .FailureTTL ) {
6960+ workspaces = append (workspaces , database.GetWorkspacesEligibleForTransitionRow {
6961+ ID :workspace .ID ,
6962+ Name :workspace .Name ,
6963+ })
69256964continue
69266965}
69276966}