Files
gozerosandCursor bd427b57a1 feat: 换到 Gin 主流栈并补齐运维能力
HTTP 用 Gin,配置用 Viper,日志用 zap,数据用 sqlx;保留原有接口与会商行为。
顺带补上就绪探活、请求号、滚动日志、systemd 与 Dockerfile。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-04 09:51:41 +08:00

76 lines
1.6 KiB
Go

package worker
import (
"sync/atomic"
"time"
"git.gozeros.com/wsk/eightbf-analysis-go/internal/domain"
"git.gozeros.com/wsk/eightbf-analysis-go/internal/logging"
"git.gozeros.com/wsk/eightbf-analysis-go/internal/repo"
)
// LiveWorker 定时扫 queued,最多并发 MaxInflight 场交给 LiveChainRunner。
type LiveWorker struct {
Repo *repo.JobRepo
Runner *LiveChainRunner
PollEvery time.Duration
MaxInflight int32
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() {
max := w.MaxInflight
if max < 1 {
max = 2
}
if atomic.LoadInt32(&w.inflight) >= max {
return
}
queued, err := w.Repo.FindQueuedJobs()
if err != nil {
logging.L.Warnw("LiveWorker 扫队列失败", "err", err)
return
}
for _, job := range queued {
if atomic.LoadInt32(&w.inflight) >= max {
break
}
job.Status = domain.StatusRunning
job.Phase = "claimed"
if err := w.Repo.UpdateProgress(job); err != nil {
logging.L.Warnw("LiveWorker 占坑失败", logging.KeyJobID, job.ID, "err", 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
}
logging.L.Infow("开始真模型会商",
logging.KeyJobID, jobID,
logging.KeyRequestID, fresh.RequestID,
logging.KeyTaskID, fresh.TaskID,
logging.KeyModel, fresh.Model,
logging.KeyStatus, fresh.Status,
)
w.Runner.Run(fresh)
}()
}
}