feat: playbook执行日志实时流式推送(SSE) + 任务详情显示原始日志
This commit is contained in:
@@ -2,6 +2,7 @@ package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ansible-deploy/internal/models"
|
||||
"github.com/ansible-deploy/internal/services"
|
||||
@@ -325,6 +326,57 @@ func (h *AnsibleHandler) GetTask(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// StreamTaskOutput SSE 流式推送任务日志
|
||||
func (h *AnsibleHandler) StreamTaskOutput(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
task := h.service.GetTask(id)
|
||||
if task == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": "任务不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/event-stream")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
c.Header("Connection", "keep-alive")
|
||||
|
||||
lastLen := 0
|
||||
for {
|
||||
// 检查客户端是否断开
|
||||
if c.Request.Context().Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
task := h.service.GetTask(id)
|
||||
if task == nil {
|
||||
return
|
||||
}
|
||||
|
||||
output := task.Output
|
||||
if len(output) > lastLen {
|
||||
// 只发送增量
|
||||
increment := output[lastLen:]
|
||||
lastLen = len(output)
|
||||
c.SSEvent("log", increment)
|
||||
c.Writer.Flush()
|
||||
}
|
||||
|
||||
if task.Status != "running" {
|
||||
// 任务完成,发送最终状态
|
||||
c.SSEvent("status", task.Status)
|
||||
c.SSEvent("error", task.Error)
|
||||
c.Writer.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
// 等 500ms 再推送
|
||||
select {
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
case <-c.Request.Context().Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CancelTask 取消任务
|
||||
func (h *AnsibleHandler) CancelTask(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
Reference in New Issue
Block a user