Skip to content

Commit b353fb8

Browse files
committed
수정: MCP long poll 종료 경계 완결
PageCommandBridge 종료 시 보류 중인 poll을 명시적 오류 응답으로 정리한다. Linux에서 fatal MCP 응답 뒤 서버 연결이 남아 종료가 지연되던 경로를 계약 테스트로 고정한다. 검증: contracts 36 suites; test:mcp 3회 연속 15/15; npm test
1 parent f10d0aa commit b353fb8

2 files changed

Lines changed: 9 additions & 1 deletion

File tree

scripts/controlProtocol/pageCommandBridge.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ export class PageCommandBridge {
119119
outcome: delivered ? "outcomeUnknown" : "notSent", retryable: !delivered,
120120
}));
121121
}
122-
this._pollWaiter = null;
122+
if (this._pollWaiter) {
123+
const waiter = this._pollWaiter;
124+
this._pollWaiter = null;
125+
waiter.deliver(null, new PageCommandError("CONTROL_BRIDGE_CLOSED", "page command bridge closed"));
126+
}
123127
}
124128

125129
_drainPoll() {

tests/contracts/controlProtocol.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,5 +311,9 @@ export async function assertControlProtocolContract() {
311311
assert(reloadError?.code === "CONTROL_PAGE_REPLACED" && reloadError.outcome === "outcomeUnknown"
312312
&& replacedPoll?.commandValue === null && replacedPoll?.error?.code === "CONTROL_PAGE_REPLACED",
313313
"page epoch 교체가 전달된 명령과 이전 poll을 fence하지 않았다");
314+
let closedPoll = null;
315+
queuedBridge.holdPoll("page:2", (commandValue, error) => { closedPoll = { commandValue, error }; });
314316
queuedBridge.close();
317+
assert(closedPoll?.commandValue === null && closedPoll?.error?.code === "CONTROL_BRIDGE_CLOSED",
318+
"page bridge 종료가 보류 중인 long poll을 닫지 않았다");
315319
}

0 commit comments

Comments
 (0)