4bc1b8d2e3
CI / docker (push) Has been cancelled
引入用户端对话/生图与管理端 Provider 配置,统一 invoke 编排、Gateway、请求日志与模型管理;前端按设计规范拆分布局,Go module 更名为 github.com/rose_cat707/Atlas;生图长任务 SSE 推送;管理端登录防爆破;协议与服务类型联动;Replicate 模型同步修复;用户端创作台 UI 重构;管理端创作历史替代请求日志。 Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
1006 B
Go
59 lines
1006 B
Go
package taskevents
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/rose_cat707/Atlas/internal/store"
|
|
)
|
|
|
|
type Hub struct {
|
|
mu sync.RWMutex
|
|
subs map[int64]map[chan store.Task]struct{}
|
|
}
|
|
|
|
func NewHub() *Hub {
|
|
return &Hub{subs: make(map[int64]map[chan store.Task]struct{})}
|
|
}
|
|
|
|
func (h *Hub) Subscribe(taskID int64) chan store.Task {
|
|
ch := make(chan store.Task, 4)
|
|
h.mu.Lock()
|
|
if h.subs[taskID] == nil {
|
|
h.subs[taskID] = make(map[chan store.Task]struct{})
|
|
}
|
|
h.subs[taskID][ch] = struct{}{}
|
|
h.mu.Unlock()
|
|
return ch
|
|
}
|
|
|
|
func (h *Hub) Unsubscribe(taskID int64, ch chan store.Task) {
|
|
h.mu.Lock()
|
|
if m, ok := h.subs[taskID]; ok {
|
|
delete(m, ch)
|
|
if len(m) == 0 {
|
|
delete(h.subs, taskID)
|
|
}
|
|
}
|
|
h.mu.Unlock()
|
|
}
|
|
|
|
func (h *Hub) Publish(task store.Task) {
|
|
h.mu.RLock()
|
|
defer h.mu.RUnlock()
|
|
for ch := range h.subs[task.ID] {
|
|
select {
|
|
case ch <- task:
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
func Terminal(status string) bool {
|
|
switch status {
|
|
case "succeeded", "failed", "canceled":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|