(ctx context.Context, log slog.Logger, db database.Store, pub pubsub.Pubsub, jobToReap *jobToReap)
| 235 | } |
| 236 | |
| 237 | func reapJob(ctx context.Context, log slog.Logger, db database.Store, pub pubsub.Pubsub, jobToReap *jobToReap) error { |
| 238 | var lowestLogID int64 |
| 239 | |
| 240 | err := db.InTx(func(db database.Store) error { |
| 241 | // Refetch the job while we hold the lock. |
| 242 | job, err := db.GetProvisionerJobByIDForUpdate(ctx, jobToReap.ID) |
| 243 | if err != nil { |
| 244 | if xerrors.Is(err, sql.ErrNoRows) { |
| 245 | return acquireLockError{} |
| 246 | } |
| 247 | return xerrors.Errorf("get provisioner job: %w", err) |
| 248 | } |
| 249 | |
| 250 | if job.CompletedAt.Valid { |
| 251 | return jobIneligibleError{ |
| 252 | Err: xerrors.Errorf("job is completed (status %s)", job.JobStatus), |
| 253 | } |
| 254 | } |
| 255 | if job.UpdatedAt.After(time.Now().Add(-jobToReap.Threshold)) { |
| 256 | return jobIneligibleError{ |
| 257 | Err: xerrors.New("job has been updated recently"), |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | log.Warn( |
| 262 | ctx, "forcefully terminating provisioner job", |
| 263 | slog.F("type", jobToReap.Type), |
| 264 | slog.F("threshold", jobToReap.Threshold), |
| 265 | ) |
| 266 | |
| 267 | // First, get the latest logs from the build so we can make sure |
| 268 | // our messages are in the latest stage. |
| 269 | logs, err := db.GetProvisionerLogsAfterID(ctx, database.GetProvisionerLogsAfterIDParams{ |
| 270 | JobID: job.ID, |
| 271 | CreatedAfter: 0, |
| 272 | }) |
| 273 | if err != nil { |
| 274 | return xerrors.Errorf("get logs for %s job: %w", jobToReap.Type, err) |
| 275 | } |
| 276 | logStage := "" |
| 277 | if len(logs) != 0 { |
| 278 | logStage = logs[len(logs)-1].Stage |
| 279 | } |
| 280 | if logStage == "" { |
| 281 | logStage = "Unknown" |
| 282 | } |
| 283 | |
| 284 | // Insert the messages into the build log. |
| 285 | insertParams := database.InsertProvisionerJobLogsParams{ |
| 286 | JobID: job.ID, |
| 287 | CreatedAt: nil, |
| 288 | Source: nil, |
| 289 | Level: nil, |
| 290 | Stage: nil, |
| 291 | Output: nil, |
| 292 | } |
| 293 | now := dbtime.Now() |
| 294 | for i, msg := range JobLogMessages(jobToReap.Type, jobToReap.Threshold) { |
no test coverage detected