Quellcode durchsuchen

fix(perf): count one-shot gateway responses as completed

彭峰 vor 11 Stunden
Ursprung
Commit
d9467d1efa

+ 1 - 1
perf/cloud-concurrency-2026-11-15/REPORT.md

@@ -40,7 +40,7 @@ node scripts/verify-read-concurrency.mjs
 
 已覆盖调度器的 50 个并发消费者、保留提交容量、共享读取取消、会话过期、队列超时、缓存 TTL/失效隔离;训练记录去重/权限/排序、游标变化检测;导出快照固定、旧租约隔离、worker 恢复和完整 XLSX 回读;门店只允许本人任务操作、worker 操作关闭;修订的插入/删除/移动/回滚/清理。
 
-独立审查发现并修复移动端登录新令牌尚未保存时被拦截、门店导出能力缺失、共享修订计数锁循环以及取消/完成竞态。最终运行数字见 VALIDATION.json。
+独立审查发现并修复移动端登录新令牌尚未保存时被拦截、门店导出能力缺失、共享修订计数锁循环以及取消/完成竞态。最后另修复 firstValueFrom 成功响应被误计为取消的计数问题,7 项调度器测试及 23 项管理端传输测试通过;最终运行数字见 VALIDATION.json。
 
 已在本机隔离 PostgreSQL 18.4 完成 7 个多连接检查:READ COMMITTED/REPEATABLE READ 下迟提交版本失效、原计数器锁循环场景、两槽跨连接准入、回滚/超时释放、50 连接超载和事件清理;结果见 postgres-concurrency.json。50 连接同时突发时 2 个进入、48 个快速繁忙,证明保护生效,不代表满足 50 用户容量目标。
 

+ 6 - 1
perf/cloud-concurrency-2026-11-15/VALIDATION.json

@@ -29,5 +29,10 @@
     "passed": 35,
     "failed": 0
   },
-  "integrationBase": "b1af307"
+  "integrationBase": "b1af307",
+  "postIntegrationCountersRegression": {
+    "schedulerTests": 7,
+    "adminTransportTests": 23,
+    "failed": 0
+  }
 }

+ 2 - 1
projects/shared/request-scheduler.ts

@@ -56,8 +56,9 @@ export class RequestScheduler {
           if (policy.valid && !policy.valid()) { subscriber.error(new Error('会话已变化,请重新查询')); return; }
           sub = defer(run).subscribe({ next: value => {
             if (policy.valid && !policy.valid()) { subscriber.error(new Error('会话已变化,请重新查询')); return; }
+            if (!ended) { ended = true; this.completed++; }
             subscriber.next(value);
-          }, error: error => subscriber.error(error), complete: () => { ended = true; this.completed++; subscriber.complete(); } });
+          }, error: error => subscriber.error(error), complete: () => { if (!ended) { ended = true; this.completed++; } subscriber.complete(); } });
         } };
         if (this.queue.length >= 64) subscriber.error(new Error('请求排队过多,请稍后重试'));
         else {

+ 4 - 0
scripts/tests/request-scheduler.test.mjs

@@ -40,3 +40,7 @@ test('fifty concurrent consumers remain bounded and a submission passes a read b
  const write=firstValueFrom(s.schedule(()=>{order.push('write');return of('saved');},{read:false}));
  assert.equal(await write,'saved');assert.equal(order[0],'write');assert.deepEqual(await Promise.all(reads),Array.from({length:50},(_,i)=>i));assert.ok(max<=3);assert.equal(s.snapshot().active,0);assert.equal(s.snapshot().queued,0);
 });
+test('firstValueFrom success counts as completion rather than consumer cancellation',async()=>{
+ const s=scheduler(),response=new Subject();const pending=firstValueFrom(s.schedule(()=>response,{read:true}));response.next(1);assert.equal(await pending,1);
+ assert.equal(s.snapshot().completed,1);assert.equal(s.snapshot().cancelled,0);
+});