1
0
mirror of https://github.com/woodpecker-ci/woodpecker.git synced 2025-11-23 21:44:44 +02:00

Show human readable information in queue info (#5516)

Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
This commit is contained in:
Robert Kaussow
2025-09-23 09:35:49 +02:00
committed by GitHub
parent 92ebabe568
commit 7707e843f2
15 changed files with 302 additions and 42 deletions

View File

@@ -37,16 +37,115 @@ import (
// GetQueueInfo
//
// @Summary Get pipeline queue information
// @Description TODO: link the InfoT response object - this is blocked, until the `swaggo/swag` tool dependency is v1.18.12 or newer
// @Description Returns pipeline queue information with agent details
// @Router /queue/info [get]
// @Produce json
// @Success 200 {object} map[string]string
// @Success 200 {object} QueueInfo
// @Tags Pipeline queues
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
func GetQueueInfo(c *gin.Context) {
c.IndentedJSON(http.StatusOK,
server.Config.Services.Queue.Info(c),
)
info := server.Config.Services.Queue.Info(c)
_store := store.FromContext(c)
// Create a map to store agent names by ID
agentNameMap := make(map[int64]string)
// Process tasks and add agent names
pendingWithAgents, err := processQueueTasks(_store, info.Pending, agentNameMap)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
waitingWithAgents, err := processQueueTasks(_store, info.WaitingOnDeps, agentNameMap)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
runningWithAgents, err := processQueueTasks(_store, info.Running, agentNameMap)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
// Create response with agent-enhanced tasks
response := model.QueueInfo{
Pending: pendingWithAgents,
WaitingOnDeps: waitingWithAgents,
Running: runningWithAgents,
Stats: struct {
WorkerCount int `json:"worker_count"`
PendingCount int `json:"pending_count"`
WaitingOnDepsCount int `json:"waiting_on_deps_count"`
RunningCount int `json:"running_count"`
}{
WorkerCount: info.Stats.Workers,
PendingCount: info.Stats.Pending,
WaitingOnDepsCount: info.Stats.WaitingOnDeps,
RunningCount: info.Stats.Running,
},
Paused: info.Paused,
}
c.IndentedJSON(http.StatusOK, response)
}
// getAgentName finds an agent's name, utilizing a map as a cache.
func getAgentName(store store.Store, agentNameMap map[int64]string, agentID int64) (string, bool) {
// 1. Check the cache first.
name, exists := agentNameMap[agentID]
if exists {
return name, true
}
// 2. If not in cache, query the store.
agent, err := store.AgentFind(agentID)
if err != nil || agent == nil {
// Agent not found or an error occurred.
return "", false
}
// 3. Found the agent, update the cache and return the name.
if agent.Name != "" {
agentNameMap[agentID] = agent.Name
return agent.Name, true
}
return "", false
}
// processQueueTasks converts tasks to QueueTask structs and adds agent names.
func processQueueTasks(store store.Store, tasks []*model.Task, agentNameMap map[int64]string) ([]model.QueueTask, error) {
result := make([]model.QueueTask, 0, len(tasks))
for _, task := range tasks {
taskResponse := model.QueueTask{
Task: *task,
}
if task.AgentID == 0 {
result = append(result, taskResponse)
continue
}
name, ok := getAgentName(store, agentNameMap, task.AgentID)
if !ok {
return nil, fmt.Errorf("agent not found for task %s", task.ID)
}
taskResponse.AgentName = name
p, err := store.GetPipeline(task.PipelineID)
if err != nil {
return nil, err
}
taskResponse.PipelineNumber = p.Number
result = append(result, taskResponse)
}
return result, nil
}
// PauseQueue