feat(eval): 评测结果回写升 JetStream 持久 —— 消灭最后一处 core NATS 回写 (P1)
完成度审计 P1 + 记忆 nats-durability 的既定规矩「计费/需落库的回写一律 JetStream+幂等,别fire-and-forget」。此前 eval 是全仓最后一处 core NATS pub-sub 回写:网关离线/慢消费者时评测结果直接丢——而质量趋势/门控都依赖它。 照抄已升级的 status/usage 范式(同为 dispatcher→gateway→PG 回写): - contract 加 StreamEval/ConsumerEval;bus 加 EnsureEvalStream + ConsumeEval (durable consumer,AckExplicit,落库失败 Nak 重投自愈),PublishEval 改 js.Publish 同步等 ack。删 core NATS 的 SubscribeEval。 - gateway/dispatcher 两个 wrapper 在 connect 时 EnsureEvalStream;gateway main 的评测订阅从 SubscribeEval(fire-and-forget)换 ConsumeEval(handler 返 error→ Nak),接入优雅停机 drain。 - 幂等前提已满足:SaveEval 按 task_id upsert,at-least-once 重投只覆盖不重复。 验证:e2e 去重测试(TestGatewayQueueDedup)升级到 ConsumeEval,50 条两副本合计 处理50次零重复;live 真端到端:提交任务→跑完→评测经新 eval 流落 PG(level=ok) 一次成功;两服务启动 eval 流 ensure 无报错。go build/vet/test 全绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -382,15 +382,20 @@ func TestGatewayQueueDedup(t *testing.T) {
|
||||
}
|
||||
defer gwB.Close()
|
||||
|
||||
// eval 流已升 JetStream;基础 bus.Connect 不 ensure(那是网关/dispatcher wrapper 的活),测试手动建。
|
||||
ctx := context.Background()
|
||||
if err := pub.EnsureEvalStream(ctx); err != nil {
|
||||
t.Fatalf("ensure eval stream: %v", err)
|
||||
}
|
||||
var total int64
|
||||
count := func(_ *contract.EvalEvent) { atomic.AddInt64(&total, 1) }
|
||||
if _, err := gwA.SubscribeEval(count); err != nil {
|
||||
t.Fatalf("gwA sub: %v", err)
|
||||
count := func(_ context.Context, _ *contract.EvalEvent) error { atomic.AddInt64(&total, 1); return nil }
|
||||
if _, err := gwA.ConsumeEval(ctx, count); err != nil {
|
||||
t.Fatalf("gwA consume: %v", err)
|
||||
}
|
||||
if _, err := gwB.SubscribeEval(count); err != nil {
|
||||
t.Fatalf("gwB sub: %v", err)
|
||||
if _, err := gwB.ConsumeEval(ctx, count); err != nil {
|
||||
t.Fatalf("gwB consume: %v", err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond) // 等订阅就绪
|
||||
time.Sleep(100 * time.Millisecond) // 等消费者就绪
|
||||
|
||||
const n = 50
|
||||
for i := 0; i < n; i++ {
|
||||
|
||||
Reference in New Issue
Block a user