9470a127f7
build / build (push) Successful in 1m11s
统一AI分析入口及双任务安全确认,采用全量载入的可见行渲染,保留完整原文。 右侧非模态详情固定五项质量字段,清理冗余展示并对齐查询和同步按钮。 默认4并发由数据库准入与逐任务租约保护,保留共享限流冷却、截断归因和有界重试。 兼容真实引用标题字段,不伪造证据或准确率,不修改源生产问答与公司区域规则。 验证:完整make verify退出0,710项Go通过、124项已声明可选跳过且必需0跳过; 另全量mirror隔离PostgreSQL race退出0,AI单元race退出0。 真实本地浏览器通过六项交互、390px内滚动及显式AI部分失败/零缺口故障夹具。 治理原生备份已真实恢复,schema57、72表计数与29张QA内容哈希一致。 候选镜像、精确提交CI与正式上线验收待本次提交后执行,不宣称已部署。
71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package qaopsai
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Admission is fenced in PostgreSQL; slow model calls do not serialize source-sync or the other AI slots.
|
|
func (s *Store) Run(ctx context.Context, onError func(error)) {
|
|
if !s.valid() {
|
|
if onError != nil {
|
|
onError(ErrUnavailable)
|
|
}
|
|
return
|
|
}
|
|
var lock sync.Mutex
|
|
var lastError time.Time
|
|
report := func(err error) {
|
|
if err == nil || ctx.Err() != nil {
|
|
return
|
|
}
|
|
lock.Lock()
|
|
defer lock.Unlock()
|
|
if time.Since(lastError) > 30*time.Second {
|
|
lastError = time.Now()
|
|
if onError != nil {
|
|
onError(err)
|
|
}
|
|
}
|
|
}
|
|
var workers sync.WaitGroup
|
|
for i := 0; i < s.concurrency(); i++ {
|
|
workers.Add(1)
|
|
go func() {
|
|
defer workers.Done()
|
|
for ctx.Err() == nil {
|
|
worked, err := s.ProcessOne(ctx)
|
|
report(err)
|
|
if !worked || err != nil {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-time.After(time.Second):
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
defer workers.Wait()
|
|
tick := time.NewTicker(10 * time.Second)
|
|
defer tick.Stop()
|
|
scan := func() {
|
|
scanCtx, cancel := context.WithTimeout(ctx, 15*time.Second)
|
|
defer cancel()
|
|
_, err := s.ScanAutomatic(scanCtx)
|
|
report(err)
|
|
_, err = s.pool.Exec(scanCtx, `INSERT INTO qa_ops_ai_runtime(tenant_key,heartbeat_at)VALUES($1,clock_timestamp())ON CONFLICT(tenant_key)DO UPDATE SET heartbeat_at=EXCLUDED.heartbeat_at`, s.tenant)
|
|
report(err)
|
|
}
|
|
scan()
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-tick.C:
|
|
scan()
|
|
}
|
|
}
|
|
}
|