mirror of
https://github.com/go-gitea/gitea
synced 2025-07-27 04:38:36 +00:00
feat: receive task logs
This commit is contained in:
@@ -8,14 +8,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TaskLog represents a task's log, every task has a standalone table
|
// TaskLog represents a task's log, every task has a standalone table
|
||||||
type TaskLog struct {
|
type TaskLog struct {
|
||||||
ID int64
|
ID int64
|
||||||
Content string `xorm:"BINARY"`
|
Timestamp timeutil.TimeStamp
|
||||||
Created timeutil.TimeStamp `xorm:"created"`
|
Content string `xorm:"LONGTEXT"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -26,16 +27,16 @@ func GetTaskLogTableName(taskID int64) string {
|
|||||||
return fmt.Sprintf("bots_task_log_%d", taskID)
|
return fmt.Sprintf("bots_task_log_%d", taskID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateTaskLog table for a build
|
// CreateTaskLog table for a task
|
||||||
func CreateTaskLog(buildID int64) error {
|
func CreateTaskLog(taskID int64) error {
|
||||||
return db.GetEngine(db.DefaultContext).
|
return db.GetEngine(db.DefaultContext).
|
||||||
Table(GetBuildLogTableName(buildID)).
|
Table(GetTaskLogTableName(taskID)).
|
||||||
Sync2(new(BuildLog))
|
Sync(new(TaskLog))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTaskLogs(taskID, index, length int64) (logs []*TaskLog, err error) {
|
func GetTaskLogs(taskID, index, length int64) (logs []*TaskLog, err error) {
|
||||||
sess := db.GetEngine(db.DefaultContext).Table(GetBuildLogTableName(taskID)).
|
sess := db.GetEngine(db.DefaultContext).Table(GetBuildLogTableName(taskID)).
|
||||||
Where("id>=?", index)
|
Where("id>=?", index).OrderBy("id")
|
||||||
|
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
sess.Limit(int(length))
|
sess.Limit(int(length))
|
||||||
@@ -45,3 +46,36 @@ func GetTaskLogs(taskID, index, length int64) (logs []*TaskLog, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InsertTaskLogs(taskID int64, logs []*TaskLog) (int64, error) {
|
||||||
|
if err := CreateTaskLog(taskID); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
table := GetTaskLogTableName(taskID)
|
||||||
|
|
||||||
|
// TODO: A more complete way to insert logs
|
||||||
|
// Be careful:
|
||||||
|
// - the id of a log can be 0
|
||||||
|
// - some logs may already exist in db
|
||||||
|
// - if use exec, consider different databases
|
||||||
|
// - the input should be ordered by id
|
||||||
|
// - the ids should be continuously increasing
|
||||||
|
// - the min id of input should be 1 + (the max id in db)
|
||||||
|
|
||||||
|
if len(logs) == 0 {
|
||||||
|
return 0, fmt.Errorf("no logs")
|
||||||
|
}
|
||||||
|
ack := logs[0].ID - 1
|
||||||
|
|
||||||
|
sess := db.GetEngine(db.DefaultContext)
|
||||||
|
for _, v := range logs {
|
||||||
|
_, err := sess.Exec(fmt.Sprintf("INSERT IGNORE INTO %s (id, timestamp, content) VALUES (?,?,?)", table), v.ID, v.Timestamp, []byte(v.Content))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("insert log %d of task %d: %v", v.ID, taskID, err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ack = v.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
return ack, nil
|
||||||
|
}
|
||||||
|
@@ -17,7 +17,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/repo"
|
"code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/user"
|
"code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
|
runnerv1 "gitea.com/gitea/proto-go/runner/v1"
|
||||||
"gitea.com/gitea/proto-go/runner/v1/runnerv1connect"
|
"gitea.com/gitea/proto-go/runner/v1/runnerv1connect"
|
||||||
|
|
||||||
@@ -180,11 +180,31 @@ func (s *Service) UpdateLog(
|
|||||||
) (*connect.Response[runnerv1.UpdateLogResponse], error) {
|
) (*connect.Response[runnerv1.UpdateLogResponse], error) {
|
||||||
res := connect.NewResponse(&runnerv1.UpdateLogResponse{})
|
res := connect.NewResponse(&runnerv1.UpdateLogResponse{})
|
||||||
|
|
||||||
// to debug
|
if len(req.Msg.Rows) == 0 {
|
||||||
for i, row := range req.Msg.Rows {
|
// TODO: should be 1 + the max id of stored log
|
||||||
log.Info("log[%v]: %v %v", req.Msg.Index+int64(i), row.Time.AsTime().Local().Format(time.RFC3339), row.Content)
|
res.Msg.AckIndex = req.Msg.Index
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rowIndex := req.Msg.Index
|
||||||
|
rows := make([]*bots_model.TaskLog, len(req.Msg.Rows))
|
||||||
|
for i, v := range req.Msg.Rows {
|
||||||
|
rows[i] = &bots_model.TaskLog{
|
||||||
|
ID: rowIndex + int64(i),
|
||||||
|
Timestamp: timeutil.TimeStamp(v.Time.AsTime().Unix()),
|
||||||
|
Content: v.Content,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ack, err := bots_model.InsertTaskLogs(req.Msg.TaskId, rows)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "insert task log: %v", err)
|
||||||
|
}
|
||||||
|
res.Msg.AckIndex = ack
|
||||||
|
|
||||||
|
if req.Msg.NoMore {
|
||||||
|
// TODO: transfer logs to storage from db
|
||||||
}
|
}
|
||||||
res.Msg.AckIndex = req.Msg.Index + int64(len(req.Msg.Rows))
|
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user