CalculateAutostop calculates the deadline and max_deadline for a workspace build. Deadline is the time when the workspace will be stopped, as long as it doesn't see any new activity (such as SSH, app requests, etc.). When activity is detected the deadline is bumped by the workspace's TTL (this only
(ctx context.Context, params CalculateAutostopParams)
| 104 | // the autobuild package. As stated above, the MaxDeadline property is only used |
| 105 | // to cap the value of a build's deadline. |
| 106 | func CalculateAutostop(ctx context.Context, params CalculateAutostopParams) (AutostopTime, error) { |
| 107 | ctx, span := tracing.StartSpan(ctx, |
| 108 | trace.WithAttributes(attribute.String("coder.workspace_id", params.Workspace.ID.String())), |
| 109 | trace.WithAttributes(attribute.String("coder.template_id", params.Workspace.TemplateID.String())), |
| 110 | ) |
| 111 | defer span.End() |
| 112 | |
| 113 | var ( |
| 114 | db = params.Database |
| 115 | workspace = params.Workspace |
| 116 | buildCompletedAt = params.WorkspaceBuildCompletedAt |
| 117 | |
| 118 | autostop AutostopTime |
| 119 | ) |
| 120 | |
| 121 | templateSchedule, err := params.TemplateScheduleStore.Get(ctx, db, workspace.TemplateID) |
| 122 | if err != nil { |
| 123 | return autostop, xerrors.Errorf("get template schedule options: %w", err) |
| 124 | } |
| 125 | |
| 126 | ttl := workspaceTTL(workspace, templateSchedule) |
| 127 | if ttl > 0 { |
| 128 | // Only apply non-zero TTLs. |
| 129 | autostop.Deadline = buildCompletedAt.Add(ttl) |
| 130 | if params.WorkspaceAutostart != "" { |
| 131 | // If the deadline passes the next autostart, we need to extend the deadline to |
| 132 | // autostart + deadline. ActivityBumpWorkspace already covers this case |
| 133 | // when extending the deadline. |
| 134 | // |
| 135 | // Situation this is solving. |
| 136 | // 1. User has workspace with auto-start at 9:00am, 12 hour auto-stop. |
| 137 | // 2. Coder stops workspace at 9pm |
| 138 | // 3. User starts workspace at 9:45pm. |
| 139 | // - The initial deadline is calculated to be 9:45am |
| 140 | // - This crosses the autostart deadline, so the deadline is extended to 9pm |
| 141 | nextAutostart, ok := NextAutostart(params.WorkspaceBuildCompletedAt, params.WorkspaceAutostart, templateSchedule) |
| 142 | if ok && autostop.Deadline.After(nextAutostart) { |
| 143 | autostop.Deadline = nextAutostart.Add(ttl) |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | // Enforce the template autostop requirement if it's configured correctly. |
| 149 | if templateSchedule.AutostopRequirement.DaysOfWeek != 0 { |
| 150 | // The template has a autostop requirement, so determine the max deadline |
| 151 | // of this workspace build. |
| 152 | |
| 153 | // First, get the user's quiet hours schedule (this will return the |
| 154 | // default if the user has not set their own schedule). |
| 155 | userQuietHoursSchedule, err := params.UserQuietHoursScheduleStore.Get(ctx, db, workspace.OwnerID) |
| 156 | if err != nil { |
| 157 | return autostop, xerrors.Errorf("get user quiet hours schedule options: %w", err) |
| 158 | } |
| 159 | |
| 160 | // If the schedule is nil, that means the deployment isn't entitled to |
| 161 | // use quiet hours. In this case, do not set a max deadline on the |
| 162 | // workspace. |
| 163 | if userQuietHoursSchedule.Schedule != nil { |