提交闸门覆盖了整个生成过程:`submit()` 会一直等到任务出结果才在 finally 里放闸。 于是上一条视频还在跑时点发送会被 `tryAcquire()` 静默拒绝——没有提示、没有反应, 用户只看到按钮在转,以为坏了;重试走的是同一条 submit 路径,一并被挡住。 闸门本来只需要防住「同一次创建任务被重复触发」(连点、回车连击),不该跨越整个 生成过程: - 闸门改为令牌制:`tryAcquire()` 返回令牌,`release(token)` 只对持有者生效, 避免并发提交互相解锁; - 任务一旦建成(bindTask)立刻放闸,与已有的 `busy` 释放时机对齐,因此上一条在 生成时也能继续提交下一条; - 被拒绝时给出提示,而不是静默丢弃(这条以前完全没反馈); - 同步更新闸门单测,补上持有者令牌的并发用例。 验证:`tsc --noEmit`、ESLint、`bun run build` 通过;`bun test` 2204 通过, 唯一失败项 agent-api-reliability 在纯净上游基线上同样失败,与本改动无关。
36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
|
|
import { createCreationSubmitGate } from "../src/pages/create/creation-submit-gate";
|
|
|
|
test("creation submit gate rejects a second submit until the first submit releases it", () => {
|
|
const gate = createCreationSubmitGate();
|
|
|
|
const token = gate.tryAcquire();
|
|
expect(token).not.toBeNull();
|
|
expect(gate.tryAcquire()).toBeNull();
|
|
|
|
gate.release(token!);
|
|
|
|
expect(gate.tryAcquire()).not.toBeNull();
|
|
});
|
|
|
|
test("释放令牌只对持有者生效,并发提交不会互相解锁", () => {
|
|
const gate = createCreationSubmitGate();
|
|
|
|
const first = gate.tryAcquire();
|
|
expect(first).not.toBeNull();
|
|
// 第二个提交拿不到锁;它释放自己的“空令牌”不该解开第一个提交。
|
|
const second = gate.tryAcquire();
|
|
expect(second).toBeNull();
|
|
gate.release(second as unknown as symbol);
|
|
expect(gate.tryAcquire()).toBeNull();
|
|
|
|
// 持有者释放后才轮得到下一次提交。
|
|
gate.release(first!);
|
|
const third = gate.tryAcquire();
|
|
expect(third).not.toBeNull();
|
|
// 已释放过的旧令牌不能解开新持有者的锁。
|
|
gate.release(first!);
|
|
expect(gate.tryAcquire()).toBeNull();
|
|
});
|