From e68b9d00a6e05b3a941f63ffb696f91e554ac5ec Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 18 Oct 2024 20:33:49 +0200 Subject: Adding upstream version 9.0.3. Signed-off-by: Daniel Baumann --- services/actions/clear_tasks.go | 101 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 services/actions/clear_tasks.go (limited to 'services/actions/clear_tasks.go') diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go new file mode 100644 index 0000000..6737378 --- /dev/null +++ b/services/actions/clear_tasks.go @@ -0,0 +1,101 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "context" + "fmt" + "time" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/timeutil" +) + +// StopZombieTasks stops the task which have running status, but haven't been updated for a long time +func StopZombieTasks(ctx context.Context) error { + return stopTasks(ctx, actions_model.FindTaskOptions{ + Status: actions_model.StatusRunning, + UpdatedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.ZombieTaskTimeout).Unix()), + }) +} + +// StopEndlessTasks stops the tasks which have running status and continuous updates, but don't end for a long time +func StopEndlessTasks(ctx context.Context) error { + return stopTasks(ctx, actions_model.FindTaskOptions{ + Status: actions_model.StatusRunning, + StartedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.EndlessTaskTimeout).Unix()), + }) +} + +func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error { + tasks, err := db.Find[actions_model.ActionTask](ctx, opts) + if err != nil { + return fmt.Errorf("find tasks: %w", err) + } + + jobs := make([]*actions_model.ActionRunJob, 0, len(tasks)) + for _, task := range tasks { + if err := db.WithTx(ctx, func(ctx context.Context) error { + if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil { + return err + } + if err := task.LoadJob(ctx); err != nil { + return err + } + jobs = append(jobs, task.Job) + return nil + }); err != nil { + log.Warn("Cannot stop task %v: %v", task.ID, err) + continue + } + + remove, err := actions.TransferLogs(ctx, task.LogFilename) + if err != nil { + log.Warn("Cannot transfer logs of task %v: %v", task.ID, err) + continue + } + task.LogInStorage = true + if err := actions_model.UpdateTask(ctx, task, "log_in_storage"); err != nil { + log.Warn("Cannot update task %v: %v", task.ID, err) + continue + } + remove() + } + + CreateCommitStatus(ctx, jobs...) + + return nil +} + +// CancelAbandonedJobs cancels the jobs which have waiting status, but haven't been picked by a runner for a long time +func CancelAbandonedJobs(ctx context.Context) error { + jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{ + Statuses: []actions_model.Status{actions_model.StatusWaiting, actions_model.StatusBlocked}, + UpdatedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.AbandonedJobTimeout).Unix()), + }) + if err != nil { + log.Warn("find abandoned tasks: %v", err) + return err + } + + now := timeutil.TimeStampNow() + for _, job := range jobs { + job.Status = actions_model.StatusCancelled + job.Stopped = now + if err := db.WithTx(ctx, func(ctx context.Context) error { + _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped") + return err + }); err != nil { + log.Warn("cancel abandoned job %v: %v", job.ID, err) + // go on + } + CreateCommitStatus(ctx, job) + } + + return nil +} -- cgit v1.2.3