Files
eightbf-analysis-go/internal/worker/live_worker.go
T
gozerosandCursor 0c45b86d67 chore: 初始化 eightbf-analysis-go(对齐 Java 会商作业服务)
Go 实现 /api/v1/analysis 契约、Demo/Live Worker、DeerFlow SSE;含设计文档与冒烟脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-03 00:13:46 +08:00

65 lines
1.3 KiB
Go

package worker
import (
"log"
"sync/atomic"
"time"
"git.gozeros.com/wsk/eightbf-analysis-go/internal/domain"
"git.gozeros.com/wsk/eightbf-analysis-go/internal/repo"
)
// LiveWorker 定时扫 queued,最多并发 2 场交给 LiveChainRunner。
type LiveWorker struct {
Repo *repo.JobRepo
Runner *LiveChainRunner
PollEvery time.Duration
inflight int32
}
func (w *LiveWorker) Start() {
if w.PollEvery <= 0 {
w.PollEvery = time.Second
}
go func() {
t := time.NewTicker(w.PollEvery)
defer t.Stop()
for range t.C {
w.poll()
}
}()
}
func (w *LiveWorker) poll() {
if atomic.LoadInt32(&w.inflight) >= 2 {
return
}
queued, err := w.Repo.FindQueuedJobs()
if err != nil {
log.Printf("LiveWorker 扫队列失败: %v", err)
return
}
for _, job := range queued {
if atomic.LoadInt32(&w.inflight) >= 2 {
break
}
job.Status = domain.StatusRunning
job.Phase = "claimed"
if err := w.Repo.UpdateProgress(job); err != nil {
log.Printf("LiveWorker 占坑失败 jobId=%s: %v", job.ID, err)
continue
}
atomic.AddInt32(&w.inflight, 1)
jobID := job.ID
go func() {
defer atomic.AddInt32(&w.inflight, -1)
fresh, err := w.Repo.FindByID(jobID)
if err != nil || fresh == nil {
return
}
log.Printf("开始真模型会商 jobId=%s", jobID)
w.Runner.Run(fresh)
}()
}
}