# Code Review Reference — REVIEW_DART_API ## 개요 task=dart_close_fix, plan=0, tag=REVIEW_DART_API ## 구현 항목별 완료 여부 | 항목 | 완료 | 비고 | |------|------|------| | [REVIEW_DART_API-1] sendRequest pending future hang 수정 | [x] | `Communicator.cancelPendingRequests()` 추가 및 `BaseClient.close()`에서 호출 | | [REVIEW_DART_API-2] onDisconnectedClient unawaited close 명시 | [x] | TCP/WS 서버 disconnect 콜백에서 `unawaited(client.close())` 사용 | | [REVIEW_DART_API-3] disconnect 통보 순서 Go 기준 정렬 | [x] | transport close 완료 후 disconnect listener 통보 | ## 계획 대비 변경 사항 계획서 그대로 구현. 테스트에서는 `@protected` 멤버 접근 analyzer 경고를 피하기 위해 `_FakeCommunicator.closeForTest()` wrapper를 추가했다. ## 주요 설계 결정 - pending request 취소는 `_pendingRequests` snapshot 생성 후 clear, 이후 각 completer에 `StateError('connection closed')`를 전달하는 순서로 구현했다. - `BaseClient.close()`는 `isAlive = false`, heartbeat 중지, pending request 취소, transport close, disconnect listener 통보 순서로 정렬했다. - `onDisconnectedClient`의 `close()` 호출은 fire-and-forget 의도를 `dart:async`의 `unawaited()`로 명시했다. ## 리뷰어를 위한 체크포인트 - `dart/lib/src/communicator.dart:56` — `cancelPendingRequests()`가 pending request를 모두 `StateError('connection closed')`로 완료하는지 확인. - `dart/lib/src/base_client.dart:31` — close 순서가 pending 취소 후 transport close, 이후 listener 통보인지 확인. - `dart/lib/src/protobuf_server.dart:67` — TCP disconnect 콜백에서 `unawaited(client.close())` 사용 확인. - `dart/lib/src/ws_protobuf_server.dart:68` — WS disconnect 콜백에서 `unawaited(client.close())` 사용 확인. - `dart/test/communicator_test.dart:66` — close 후 pending `sendRequest` future가 `StateError`로 완료되는 회귀 테스트 확인. ## 검증 결과 ``` $ cd dart && dart analyze Analyzing dart... No issues found! $ cd dart && dart test test/communicator_test.dart 00:00 +0: loading test/communicator_test.dart 00:00 +0: Communicator protocol guards response typeName mismatch completes sendRequest with error 00:00 +1: Communicator protocol guards close 후 sendRequest는 StateError로 완료된다 00:00 +2: Communicator protocol guards cannot register addRequestListener for a type already using addListener 00:00 +3: Communicator protocol guards cannot register addListener for a type already using addRequestListener 00:00 +4: All tests passed! $ cd dart && dart format lib/src/communicator.dart lib/src/base_client.dart lib/src/protobuf_server.dart lib/src/ws_protobuf_server.dart test/communicator_test.dart Formatted lib/src/communicator.dart Formatted 5 files (1 changed) in 0.11 seconds. $ cd dart && dart test 00:15 +40: All tests passed! $ cd dart && dart analyze Analyzing dart... No issues found! ```