feat: update runner status

This commit is contained in:
Jason Song 2022-11-16 10:54:53 +08:00
parent 745be45e1b
commit 7059cd7265
6 changed files with 52 additions and 58 deletions

View File

@ -7,6 +7,8 @@ package bots
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time"
auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -54,14 +56,14 @@ type Runner struct {
TokenSalt string TokenSalt string
// TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token // TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token
// instance status (idle, active, offline) LastOnline timeutil.TimeStamp `xorm:"index"`
Status runnerv1.RunnerStatus LastActive timeutil.TimeStamp `xorm:"index"`
// Store OS and Artch. // Store OS and Artch.
AgentLabels []string AgentLabels []string
// Store custom labes use defined. // Store custom labes use defined.
CustomLabels []string CustomLabels []string
LastOnline timeutil.TimeStamp `xorm:"index"`
Created timeutil.TimeStamp `xorm:"created"` Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"` Updated timeutil.TimeStamp `xorm:"updated"`
Deleted timeutil.TimeStamp `xorm:"deleted"` Deleted timeutil.TimeStamp `xorm:"deleted"`
@ -82,16 +84,26 @@ func (r *Runner) OwnType() string {
return r.Repo.FullName() return r.Repo.FullName()
} }
func (r *Runner) StatusType() string { func (r *Runner) Status() runnerv1.RunnerStatus {
switch r.Status { if time.Since(r.LastOnline.AsTime()) > time.Minute {
case runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE: return runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE
return "offline"
case runnerv1.RunnerStatus_RUNNER_STATUS_IDLE:
return "online"
case runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE:
return "online"
} }
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 // AllLabels returns agent and custom labels

View File

@ -27,14 +27,14 @@ func addBotTables(x *xorm.Engine) error {
TokenSalt string TokenSalt string
// TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token // TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token
// instance status (idle, active, offline) LastOnline timeutil.TimeStamp `xorm:"index"`
Status int32 LastActive timeutil.TimeStamp `xorm:"index"`
// Store OS and Artch. // Store OS and Artch.
AgentLabels []string AgentLabels []string
// Store custom labes use defined. // Store custom labes use defined.
CustomLabels []string CustomLabels []string
LastOnline timeutil.TimeStamp `xorm:"index"`
Created timeutil.TimeStamp `xorm:"created"` Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"` Updated timeutil.TimeStamp `xorm:"updated"`
Deleted timeutil.TimeStamp `xorm:"deleted"` Deleted timeutil.TimeStamp `xorm:"deleted"`

View File

@ -38,22 +38,10 @@ type Service struct {
// UpdateRunner update runner status or other data. // UpdateRunner update runner status or other data.
func (s *Service) UpdateRunner( func (s *Service) UpdateRunner(
ctx context.Context, _ context.Context,
req *connect.Request[runnerv1.UpdateRunnerRequest], _ *connect.Request[runnerv1.UpdateRunnerRequest],
) (*connect.Response[runnerv1.UpdateRunnerResponse], error) { ) (*connect.Response[runnerv1.UpdateRunnerResponse], error) {
runner := GetRunner(ctx) // FIXME: we don't need it any longer
// 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)
}
return connect.NewResponse(&runnerv1.UpdateRunnerResponse{}), nil return connect.NewResponse(&runnerv1.UpdateRunnerResponse{}), nil
} }
@ -81,7 +69,6 @@ func (s *Service) Register(
Name: req.Msg.Name, Name: req.Msg.Name,
OwnerID: runnerToken.OwnerID, OwnerID: runnerToken.OwnerID,
RepoID: runnerToken.RepoID, RepoID: runnerToken.RepoID,
Status: runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE,
AgentLabels: req.Msg.AgentLabels, AgentLabels: req.Msg.AgentLabels,
CustomLabels: req.Msg.CustomLabels, CustomLabels: req.Msg.CustomLabels,
} }
@ -108,7 +95,6 @@ func (s *Service) Register(
Name: runner.Name, Name: runner.Name,
AgentLabels: runner.AgentLabels, AgentLabels: runner.AgentLabels,
CustomLabels: runner.CustomLabels, CustomLabels: runner.CustomLabels,
Status: runner.Status,
}, },
}) })

View File

@ -14,21 +14,20 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
"github.com/bufbuild/connect-go" "github.com/bufbuild/connect-go"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
const ( const (
runnerOnlineTimeDeltaSecs = 30
uuidHeaderKey = "x-runner-uuid" uuidHeaderKey = "x-runner-uuid"
tokenHeaderKey = "x-runner-token" tokenHeaderKey = "x-runner-token"
) )
var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unaryFunc connect.UnaryFunc) connect.UnaryFunc { var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unaryFunc connect.UnaryFunc) connect.UnaryFunc {
return func(ctx context.Context, request connect.AnyRequest) (connect.AnyResponse, error) { 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) return unaryFunc(ctx, request)
} }
uuid := request.Header().Get(uuidHeaderKey) uuid := request.Header().Get(uuidHeaderKey)
@ -44,27 +43,22 @@ var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar
return nil, status.Error(codes.Unauthenticated, "unregistered runner") return nil, status.Error(codes.Unauthenticated, "unregistered runner")
} }
// update runner online status cols := []string{"last_online"}
if runner.Status == runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE {
runner.LastOnline = timeutil.TimeStampNow() runner.LastOnline = timeutil.TimeStampNow()
runner.Status = runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE if methodName == "UpdateTask" || methodName == "UpdateLog" {
if err := bots_model.UpdateRunner(ctx, runner, "last_online", "status"); err != nil { runner.LastActive = timeutil.TimeStampNow()
cols = append(cols, "last_active")
}
if err := bots_model.UpdateRunner(ctx, runner, cols...); err != nil {
log.Error("can't update runner status: %v", err) log.Error("can't update runner status: %v", err)
} }
}
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)
}
}
ctx = context.WithValue(ctx, runnerCtxKey{}, runner) ctx = context.WithValue(ctx, runnerCtxKey{}, runner)
return unaryFunc(ctx, request) return unaryFunc(ctx, request)
} }
})) }))
func methodName(req connect.AnyRequest) string { func getMethodName(req connect.AnyRequest) string {
splits := strings.Split(req.Spec().Procedure, "/") splits := strings.Split(req.Spec().Procedure, "/")
if len(splits) > 0 { if len(splits) > 0 {
return splits[len(splits)-1] return splits[len(splits)-1]

View File

@ -10,7 +10,7 @@
<div class="runner-basic-info"> <div class="runner-basic-info">
<div class="field dib"> <div class="field dib">
<label>{{.locale.Tr "admin.runners.status"}}</label> <label>{{.locale.Tr "admin.runners.status"}}</label>
<span class="runner-status-{{.Runner.StatusType}}">{{.Runner.StatusType}}</span> <span class="runner-status-{{if .Runner.IsOnline}}online{{else}}offline{{end}}">{{.Runner.StatusName}}</span>
</div> </div>
<div class="field dib"> <div class="field dib">
<label>{{.locale.Tr "admin.runners.latest_online"}}</label> <label>{{.locale.Tr "admin.runners.latest_online"}}</label>

View File

@ -60,7 +60,9 @@
<tbody> <tbody>
{{range .Runners}} {{range .Runners}}
<tr> <tr>
<td><span class="runner-status-{{.StatusType}}">{{.StatusType}}</span></td> <td>
<span class="runner-status-{{if .IsOnline}}online{{else}}offline{{end}}">{{.StatusName}}</span>
</td>
<td> <td>
{{if .Editable $.RunnerOnwerID $.RunnerRepoID}} {{if .Editable $.RunnerOnwerID $.RunnerRepoID}}
<a href="{{$.Link}}/{{.ID}}" class="tooltip" data-content="{{.Description}}"> <a href="{{$.Link}}/{{.ID}}" class="tooltip" data-content="{{.Description}}">