Files
FlowStack/backend/internal/handler/hub.go
T
Logan.Li 04d1342b27 feat: FlowStack 发布系统首个可运行版本 (gin + React)
- Go gin 后端:流水线/节点/连线/运行/日志/GitOps/插件 REST API,
  SQLite(GORM) 自动建表 + seed,模拟执行引擎 + SSE 实时日志推送,
  前端产物 go:embed 嵌入单二进制,一个端口同时服务 API 与页面
- React 19 前端:画布式流水线编辑器(React Flow + Tekton 任务库)、
  GitOps 部署、批量发布、发布记录等 14 个模块页面,
  tRPC 全部替换为 REST(TanStack Query)
- 首次启动生成随机密码管理员账号(日志 + data/initial-admin-password.txt)
- run.sh 一键构建启动(默认端口 9527,支持 start/stop/restart/build/dev)
2026-10-27 02:44:10 +08:00

57 lines
1.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"encoding/json"
"fmt"
"sync"
)
// Hub 按 runId 分组的 SSE 订阅中心
type Hub struct {
mu sync.Mutex
subs map[string]map[chan []byte]struct{}
}
func NewHub() *Hub {
return &Hub{subs: make(map[string]map[chan []byte]struct{})}
}
func (h *Hub) Subscribe(runId string) chan []byte {
ch := make(chan []byte, 64)
h.mu.Lock()
defer h.mu.Unlock()
if h.subs[runId] == nil {
h.subs[runId] = make(map[chan []byte]struct{})
}
h.subs[runId][ch] = struct{}{}
return ch
}
func (h *Hub) Unsubscribe(runId string, ch chan []byte) {
h.mu.Lock()
defer h.mu.Unlock()
if set := h.subs[runId]; set != nil {
delete(set, ch)
if len(set) == 0 {
delete(h.subs, runId)
}
}
}
// Publish 向 runId 的所有订阅者推送一条 SSE 帧(event + data)
func (h *Hub) Publish(runId, event string, payload any) {
data, err := json.Marshal(payload)
if err != nil {
return
}
frame := []byte(fmt.Sprintf("event: %s\ndata: %s\n\n", event, data))
h.mu.Lock()
defer h.mu.Unlock()
for ch := range h.subs[runId] {
select {
case ch <- frame:
default: // 订阅者消费过慢则丢弃,避免阻塞模拟引擎
}
}
}