diff --git a/models/bots/runner.go b/models/bots/runner.go index 0299c80d93..6b6ed75291 100644 --- a/models/bots/runner.go +++ b/models/bots/runner.go @@ -7,6 +7,8 @@ package bots import ( "context" "fmt" + "strings" + "time" auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" @@ -54,17 +56,17 @@ type Runner struct { TokenSalt string // TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token - // instance status (idle, active, offline) - Status runnerv1.RunnerStatus + LastOnline timeutil.TimeStamp `xorm:"index"` + LastActive timeutil.TimeStamp `xorm:"index"` + // Store OS and Artch. AgentLabels []string // Store custom labes use defined. CustomLabels []string - LastOnline timeutil.TimeStamp `xorm:"index"` - Created timeutil.TimeStamp `xorm:"created"` - Updated timeutil.TimeStamp `xorm:"updated"` - Deleted timeutil.TimeStamp `xorm:"deleted"` + Created timeutil.TimeStamp `xorm:"created"` + Updated timeutil.TimeStamp `xorm:"updated"` + Deleted timeutil.TimeStamp `xorm:"deleted"` } func (Runner) TableName() string { @@ -82,16 +84,26 @@ func (r *Runner) OwnType() string { return r.Repo.FullName() } -func (r *Runner) StatusType() string { - switch r.Status { - case runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE: - return "offline" - case runnerv1.RunnerStatus_RUNNER_STATUS_IDLE: - return "online" - case runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE: - return "online" +func (r *Runner) Status() runnerv1.RunnerStatus { + if time.Since(r.LastOnline.AsTime()) > time.Minute { + return runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE } - return "unknown" + if time.Since(r.LastActive.AsTime()) > 10*time.Second { + return runnerv1.RunnerStatus_RUNNER_STATUS_IDLE + } + return runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE +} + +func (r *Runner) StatusName() string { + return strings.ToLower(strings.TrimPrefix(r.Status().String(), "RUNNER_STATUS_")) +} + +func (r *Runner) IsOnline() bool { + status := r.Status() + if status == runnerv1.RunnerStatus_RUNNER_STATUS_IDLE || status == runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE { + return true + } + return false } // AllLabels returns agent and custom labels diff --git a/models/migrations/v-dev.go b/models/migrations/v-dev.go index 4702f9c0d9..b4f3b4d91d 100644 --- a/models/migrations/v-dev.go +++ b/models/migrations/v-dev.go @@ -27,17 +27,17 @@ func addBotTables(x *xorm.Engine) error { TokenSalt string // TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token - // instance status (idle, active, offline) - Status int32 + LastOnline timeutil.TimeStamp `xorm:"index"` + LastActive timeutil.TimeStamp `xorm:"index"` + // Store OS and Artch. AgentLabels []string // Store custom labes use defined. CustomLabels []string - LastOnline timeutil.TimeStamp `xorm:"index"` - Created timeutil.TimeStamp `xorm:"created"` - Updated timeutil.TimeStamp `xorm:"updated"` - Deleted timeutil.TimeStamp `xorm:"deleted"` + Created timeutil.TimeStamp `xorm:"created"` + Updated timeutil.TimeStamp `xorm:"updated"` + Deleted timeutil.TimeStamp `xorm:"deleted"` } type BotsRunnerToken struct { diff --git a/routers/api/bots/runner/runner.go b/routers/api/bots/runner/runner.go index 555cb80cc2..d5e5f17da1 100644 --- a/routers/api/bots/runner/runner.go +++ b/routers/api/bots/runner/runner.go @@ -38,22 +38,10 @@ type Service struct { // UpdateRunner update runner status or other data. func (s *Service) UpdateRunner( - ctx context.Context, - req *connect.Request[runnerv1.UpdateRunnerRequest], + _ context.Context, + _ *connect.Request[runnerv1.UpdateRunnerRequest], ) (*connect.Response[runnerv1.UpdateRunnerResponse], error) { - runner := GetRunner(ctx) - - // check status - if runner.Status == req.Msg.Status { - return connect.NewResponse(&runnerv1.UpdateRunnerResponse{}), nil - } - - // update status - runner.Status = req.Msg.Status - if err := bots_model.UpdateRunner(ctx, runner, "status"); err != nil { - return nil, connect.NewError(connect.CodeInternal, err) - } - + // FIXME: we don't need it any longer return connect.NewResponse(&runnerv1.UpdateRunnerResponse{}), nil } @@ -81,7 +69,6 @@ func (s *Service) Register( Name: req.Msg.Name, OwnerID: runnerToken.OwnerID, RepoID: runnerToken.RepoID, - Status: runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE, AgentLabels: req.Msg.AgentLabels, CustomLabels: req.Msg.CustomLabels, } @@ -108,7 +95,6 @@ func (s *Service) Register( Name: runner.Name, AgentLabels: runner.AgentLabels, CustomLabels: runner.CustomLabels, - Status: runner.Status, }, }) diff --git a/routers/api/bots/runner/unary.go b/routers/api/bots/runner/unary.go index a0d287da7d..7124b10e11 100644 --- a/routers/api/bots/runner/unary.go +++ b/routers/api/bots/runner/unary.go @@ -14,21 +14,20 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" - runnerv1 "gitea.com/gitea/proto-go/runner/v1" "github.com/bufbuild/connect-go" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) const ( - runnerOnlineTimeDeltaSecs = 30 - uuidHeaderKey = "x-runner-uuid" - tokenHeaderKey = "x-runner-token" + uuidHeaderKey = "x-runner-uuid" + tokenHeaderKey = "x-runner-token" ) var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unaryFunc connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, request connect.AnyRequest) (connect.AnyResponse, error) { - if methodName(request) == "Register" { + methodName := getMethodName(request) + if methodName == "Register" { return unaryFunc(ctx, request) } uuid := request.Header().Get(uuidHeaderKey) @@ -44,19 +43,14 @@ var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar return nil, status.Error(codes.Unauthenticated, "unregistered runner") } - // update runner online status - if runner.Status == runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE { - runner.LastOnline = timeutil.TimeStampNow() - runner.Status = runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE - if err := bots_model.UpdateRunner(ctx, runner, "last_online", "status"); err != nil { - log.Error("can't update runner status: %v", err) - } + cols := []string{"last_online"} + runner.LastOnline = timeutil.TimeStampNow() + if methodName == "UpdateTask" || methodName == "UpdateLog" { + runner.LastActive = timeutil.TimeStampNow() + cols = append(cols, "last_active") } - if timeutil.TimeStampNow()-runner.LastOnline >= runnerOnlineTimeDeltaSecs { - runner.LastOnline = timeutil.TimeStampNow() - if err := bots_model.UpdateRunner(ctx, runner, "last_online"); err != nil { - log.Error("can't update runner last_online: %v", err) - } + if err := bots_model.UpdateRunner(ctx, runner, cols...); err != nil { + log.Error("can't update runner status: %v", err) } ctx = context.WithValue(ctx, runnerCtxKey{}, runner) @@ -64,7 +58,7 @@ var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar } })) -func methodName(req connect.AnyRequest) string { +func getMethodName(req connect.AnyRequest) string { splits := strings.Split(req.Spec().Procedure, "/") if len(splits) > 0 { return splits[len(splits)-1] diff --git a/templates/runners/edit.tmpl b/templates/runners/edit.tmpl index dc974a3cfc..51321fd8f8 100644 --- a/templates/runners/edit.tmpl +++ b/templates/runners/edit.tmpl @@ -10,7 +10,7 @@