mirror of https://code.forgejo.org/forgejo/runner
chore(runner): cancel task if get the cancel from server
Signed-off-by: Bo-Yi.Wu <appleboy.tw@gmail.com>pull/2/head
parent
d178051832
commit
08c94bb564
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module gitea.com/gitea/act_runner
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b
|
gitea.com/gitea/proto-go v0.0.0-20221028125601-35c4f6b05835
|
||||||
github.com/appleboy/com v0.1.6
|
github.com/appleboy/com v0.1.6
|
||||||
github.com/avast/retry-go/v4 v4.1.0
|
github.com/avast/retry-go/v4 v4.1.0
|
||||||
github.com/bufbuild/connect-go v0.5.0
|
github.com/bufbuild/connect-go v0.5.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -27,6 +27,8 @@ gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa h1:HHqlvfIvqFlny3sgJgAM1B
|
||||||
gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa/go.mod h1:9W/Nz16tjfnWp7O5DUo3EjZBnZFBI/5rlWstX4o7+hU=
|
gitea.com/gitea/act v0.0.0-20220922135643-52a5bba9e7fa/go.mod h1:9W/Nz16tjfnWp7O5DUo3EjZBnZFBI/5rlWstX4o7+hU=
|
||||||
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b h1:TSz7VRHfnM/5JwGPgIAjSlDIvcr4pTGfuRMtgMxttmg=
|
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b h1:TSz7VRHfnM/5JwGPgIAjSlDIvcr4pTGfuRMtgMxttmg=
|
||||||
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y=
|
gitea.com/gitea/proto-go v0.0.0-20221014123629-9116865c883b/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y=
|
||||||
|
gitea.com/gitea/proto-go v0.0.0-20221028125601-35c4f6b05835 h1:27PhT7Nli/pgRo1bDYVZ+hlCKuF9cfFuo+y9muaPVJY=
|
||||||
|
gitea.com/gitea/proto-go v0.0.0-20221028125601-35c4f6b05835/go.mod h1:hD8YwSHusjwjEEgubW6XFvnZuNhMZTHz6lwjfltEt/Y=
|
||||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
|
|
|
@ -19,6 +19,8 @@ import (
|
||||||
|
|
||||||
type Reporter struct {
|
type Reporter struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
|
|
||||||
closed bool
|
closed bool
|
||||||
client client.Client
|
client client.Client
|
||||||
clientM sync.Mutex
|
clientM sync.Mutex
|
||||||
|
@ -29,9 +31,10 @@ type Reporter struct {
|
||||||
stateM sync.RWMutex
|
stateM sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReporter(ctx context.Context, client client.Client, taskID int64) *Reporter {
|
func NewReporter(ctx context.Context, cancel context.CancelFunc, client client.Client, taskID int64) *Reporter {
|
||||||
return &Reporter{
|
return &Reporter{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
cancel: cancel,
|
||||||
client: client,
|
client: client,
|
||||||
state: &runnerv1.TaskState{
|
state: &runnerv1.TaskState{
|
||||||
Id: taskID,
|
Id: taskID,
|
||||||
|
@ -218,9 +221,14 @@ func (r *Reporter) ReportState() error {
|
||||||
state := proto.Clone(r.state).(*runnerv1.TaskState)
|
state := proto.Clone(r.state).(*runnerv1.TaskState)
|
||||||
r.stateM.RUnlock()
|
r.stateM.RUnlock()
|
||||||
|
|
||||||
_, err := r.client.UpdateTask(r.ctx, connect.NewRequest(&runnerv1.UpdateTaskRequest{
|
resp, err := r.client.UpdateTask(r.ctx, connect.NewRequest(&runnerv1.UpdateTaskRequest{
|
||||||
State: state,
|
State: state,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if resp.Msg.State.Result == runnerv1.Result_RESULT_CANCELLED {
|
||||||
|
r.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,14 +243,12 @@ func (r *Reporter) duringSteps() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var stringToResult = map[string]runnerv1.Result{
|
||||||
stringToResult = map[string]runnerv1.Result{
|
|
||||||
"success": runnerv1.Result_RESULT_SUCCESS,
|
"success": runnerv1.Result_RESULT_SUCCESS,
|
||||||
"failure": runnerv1.Result_RESULT_FAILURE,
|
"failure": runnerv1.Result_RESULT_FAILURE,
|
||||||
"skipped": runnerv1.Result_RESULT_SKIPPED,
|
"skipped": runnerv1.Result_RESULT_SKIPPED,
|
||||||
"cancelled": runnerv1.Result_RESULT_CANCELLED,
|
"cancelled": runnerv1.Result_RESULT_CANCELLED,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
func (r *Reporter) parseResult(result interface{}) (runnerv1.Result, bool) {
|
func (r *Reporter) parseResult(result interface{}) (runnerv1.Result, bool) {
|
||||||
str := ""
|
str := ""
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"gitea.com/gitea/act_runner/client"
|
"gitea.com/gitea/act_runner/client"
|
||||||
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
|
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
|
||||||
|
@ -18,9 +19,11 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var globalTaskMap sync.Map
|
||||||
|
|
||||||
type TaskInput struct {
|
type TaskInput struct {
|
||||||
repoDirectory string
|
repoDirectory string
|
||||||
actor string
|
// actor string
|
||||||
// workdir string
|
// workdir string
|
||||||
// workflowsPath string
|
// workflowsPath string
|
||||||
// autodetectEvent bool
|
// autodetectEvent bool
|
||||||
|
@ -57,30 +60,10 @@ type TaskInput struct {
|
||||||
EnvFile string
|
EnvFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
type TaskState int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// TaskStateUnknown is the default state
|
|
||||||
TaskStateUnknown TaskState = iota
|
|
||||||
// TaskStatePending is the pending state
|
|
||||||
// pending means task is received, parsing actions and preparing to run
|
|
||||||
TaskStatePending
|
|
||||||
// TaskStateRunning is the state when the task is running
|
|
||||||
// running means task is running
|
|
||||||
TaskStateRunning
|
|
||||||
// TaskStateSuccess is the state when the task is successful
|
|
||||||
// success means task is successful without any error
|
|
||||||
TaskStateSuccess
|
|
||||||
// TaskStateFailure is the state when the task is failed
|
|
||||||
// failure means task is failed with error
|
|
||||||
TaskStateFailure
|
|
||||||
)
|
|
||||||
|
|
||||||
type Task struct {
|
type Task struct {
|
||||||
BuildID int64
|
BuildID int64
|
||||||
Input *TaskInput
|
Input *TaskInput
|
||||||
|
|
||||||
state TaskState
|
|
||||||
client client.Client
|
client client.Client
|
||||||
log *log.Entry
|
log *log.Entry
|
||||||
}
|
}
|
||||||
|
@ -94,7 +77,6 @@ func NewTask(forgeInstance string, buildID int64, client client.Client) *Task {
|
||||||
},
|
},
|
||||||
BuildID: buildID,
|
BuildID: buildID,
|
||||||
|
|
||||||
state: TaskStatePending,
|
|
||||||
client: client,
|
client: client,
|
||||||
log: log.WithField("buildID", buildID),
|
log: log.WithField("buildID", buildID),
|
||||||
}
|
}
|
||||||
|
@ -124,6 +106,8 @@ func demoPlatforms() map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Task) Run(ctx context.Context, task *runnerv1.Task) error {
|
func (t *Task) Run(ctx context.Context, task *runnerv1.Task) error {
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
_, exist := globalTaskMap.Load(task.Id)
|
_, exist := globalTaskMap.Load(task.Id)
|
||||||
if exist {
|
if exist {
|
||||||
return fmt.Errorf("task %d already exists", task.Id)
|
return fmt.Errorf("task %d already exists", task.Id)
|
||||||
|
@ -135,11 +119,10 @@ func (t *Task) Run(ctx context.Context, task *runnerv1.Task) error {
|
||||||
defer globalTaskMap.Delete(task.Id)
|
defer globalTaskMap.Delete(task.Id)
|
||||||
|
|
||||||
lastWords := ""
|
lastWords := ""
|
||||||
reporter := NewReporter(ctx, t.client, task.Id)
|
reporter := NewReporter(ctx, cancel, t.client, task.Id)
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = reporter.Close(lastWords)
|
_ = reporter.Close(lastWords)
|
||||||
}()
|
}()
|
||||||
reporter.RunDaemon()
|
|
||||||
|
|
||||||
reporter.Logf("received task %v of job %v", task.Id, task.Context.Fields["job"].GetStringValue())
|
reporter.Logf("received task %v of job %v", task.Id, task.Context.Fields["job"].GetStringValue())
|
||||||
|
|
||||||
|
@ -157,17 +140,16 @@ func (t *Task) Run(ctx context.Context, task *runnerv1.Task) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var plan *model.Plan
|
var plan *model.Plan
|
||||||
if jobIDs := workflow.GetJobIDs(); len(jobIDs) != 1 {
|
jobIDs := workflow.GetJobIDs()
|
||||||
err := fmt.Errorf("multiple jobs fould: %v", jobIDs)
|
if len(jobIDs) != 1 {
|
||||||
|
err := fmt.Errorf("multiple jobs found: %v", jobIDs)
|
||||||
lastWords = err.Error()
|
lastWords = err.Error()
|
||||||
return err
|
return err
|
||||||
} else {
|
}
|
||||||
jobID := jobIDs[0]
|
jobID := jobIDs[0]
|
||||||
plan = model.CombineWorkflowPlanner(workflow).PlanJob(jobID)
|
plan = model.CombineWorkflowPlanner(workflow).PlanJob(jobID)
|
||||||
|
|
||||||
job := workflow.GetJob(jobID)
|
job := workflow.GetJob(jobID)
|
||||||
reporter.ResetSteps(len(job.Steps))
|
reporter.ResetSteps(len(job.Steps))
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("plan: %+v", plan.Stages[0].Runs)
|
log.Infof("plan: %+v", plan.Stages[0].Runs)
|
||||||
|
|
||||||
|
@ -234,11 +216,11 @@ func (t *Task) Run(ctx context.Context, task *runnerv1.Task) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerPort)
|
artifactCancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerPort)
|
||||||
t.log.Debugf("artifacts server started at %s:%s", input.artifactServerPath, input.artifactServerPort)
|
t.log.Debugf("artifacts server started at %s:%s", input.artifactServerPath, input.artifactServerPort)
|
||||||
|
|
||||||
executor := r.NewPlanExecutor(plan).Finally(func(ctx context.Context) error {
|
executor := r.NewPlanExecutor(plan).Finally(func(ctx context.Context) error {
|
||||||
cancel()
|
artifactCancel()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var globalTaskMap sync.Map
|
|
||||||
|
|
||||||
// finishTask removes the task from global map
|
|
||||||
func finishTask(buildID int64) {
|
|
||||||
globalTaskMap.Delete(buildID)
|
|
||||||
}
|
|
Loading…
Reference in New Issue