<!-- task=api_consistency plan=0 tag=IMPROVE -->

# Code Review Reference - IMPROVE

## 개요

date=2026-04-24
task=api_consistency, plan=0, tag=IMPROVE

## 이 파일을 읽는 리뷰 에이전트에게

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.

1. `CODE_REVIEW.md` → `code_review_0.log` (기존 code_review_*.log 수 = 0)
2. `PLAN.md` → `plan_0.log` (기존 plan_*.log 수 = 0)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [IMPROVE-1] Dart `sendRequest` timeout 파라미터 추가 | [x] |
| [IMPROVE-2] TypeScript write queue maxsize 제한 | [x] |

## 계획 대비 변경 사항

- TypeScript write loop는 첫 packet을 즉시 in-flight로 소비하므로, 테스트는 `1개 in-flight + 64개 queued` 상태에서 66번째 `queuePacket()`이 waiter에 들어가는 방식으로 검증했다.
- Dart `_pendingRequests` 정리 확인은 public API를 늘리지 않기 위해 테스트에서만 reflection으로 확인했다.

## 주요 설계 결정

- Dart `sendRequest`는 기존 호출 호환성을 유지하도록 named parameter 기본값 `Duration(seconds: 30)`을 사용했다.
- Dart timeout 발생 시 해당 nonce를 `_pendingRequests`에서 제거하고 `TimeoutException`을 전파한다.
- TypeScript write queue 제한은 queued item 수 기준 64개로 적용하고, queue item이 소비될 때 waiter를 하나씩 깨운다.
- TypeScript `shutdown()`은 대기 중인 sender를 모두 깨워 재개 시 `NotConnectedError`로 종료되도록 했다.

## 리뷰어를 위한 체크포인트

- `dart/lib/src/communicator.dart` — `sendRequest` 시그니처에 `{Duration timeout = const Duration(seconds: 30)}` 파라미터 있는지
- `dart/lib/src/communicator.dart` — timeout 발생 시 `_pendingRequests.remove(requestNonce)` 호출 후 `TimeoutException` 전파하는지
- `dart/test/communicator_test.dart` — `TimeoutException` 테스트 추가 및 통과 여부
- `typescript/src/communicator.ts` — `MAX_WRITE_QUEUE_SIZE = 64` 상수 존재 여부
- `typescript/src/communicator.ts` — `queuePacket()`에서 queue full 시 대기 로직 구현 여부
- `typescript/src/communicator.ts` — `shutdown()`에서 waiters 플러시 여부
- `typescript/src/communicator.ts` — `initialize()`에서 `writeQueueWaiters = []` 초기화 여부
- `typescript/test/communicator.test.ts` — 큐 full 대기 테스트 추가 및 통과 여부

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

### IMPROVE-1 중간 검증
```
$ cd dart && dart test 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 sendRequest가 timeout 내 응답 없으면 TimeoutException을 던진다
00:00 +3: Communicator protocol guards cannot register addRequestListener for a type already using addListener
00:00 +4: Communicator protocol guards cannot register addListener for a type already using addRequestListener
00:00 +5: Communicator protocol guards queuePacket uses injected transport
00:00 +6: All tests passed!

$ cd dart && dart analyze
No issues found!
```

### IMPROVE-2 중간 검증
```
$ cd typescript && npx tsc --noEmit
(exit 0, no output)

$ cd typescript && npx vitest run test/communicator.test.ts
✓ test/communicator.test.ts (8 tests) 20ms

Test Files  1 passed (1)
     Tests  8 passed (8)
```

### 최종 검증
```
$ cd dart && dart analyze
No issues found!

$ cd dart && dart test
00:15 +43: All tests passed!

$ cd typescript && npx tsc --noEmit
(exit 0, no output)

$ cd typescript && npx vitest run
✓ test/base_client.test.ts (7 tests) 9ms
✓ test/communicator.test.ts (8 tests) 19ms
✓ test/tcp.test.ts (2 tests) 13ms
✓ test/ws.test.ts (2 tests) 21ms

Test Files  4 passed (4)
     Tests  19 passed (19)
```
