- Align protocol documentation (PROTOCOL.md, README.md, VERSIONING.md) - Go: add nonce test, update communicator - Kotlin: update Communicator, TcpClient, TcpServer, add TLS test - Python: update all modules, add certificate test resources - TypeScript: update communicator, tcp/ws clients and servers, add tests - Dart: update communicator, heartbeat mixin, and tests
127 lines
8.2 KiB
Text
127 lines
8.2 KiB
Text
<!-- task=dart_legacy_refactor plan=0 tag=REFACTOR -->
|
|
|
|
# Code Review Reference - REFACTOR
|
|
|
|
## 개요
|
|
|
|
date=2026-04-25
|
|
task=dart_legacy_refactor, plan=0, tag=REFACTOR
|
|
|
|
## 이 파일을 읽는 리뷰 에이전트에게
|
|
|
|
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
|
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
|
|
|
|
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` 스텁 작성.
|
|
|
|
---
|
|
|
|
## 구현 항목별 완료 여부
|
|
|
|
| 항목 | 완료 여부 |
|
|
|------|---------|
|
|
| [REFACTOR-1] `communicator.dart` `send()` concrete 구현 + 레거시 삭제 | [x] |
|
|
| [REFACTOR-2] `communicator_test.dart` `_FakeCommunicator.send()` 오버라이드 제거 | [x] |
|
|
|
|
## 계획 대비 변경 사항
|
|
|
|
- 현재 작업트리에 nonce overflow 정책(`maxNonce`, `nextNonce()`)이 적용되어 있어, 새 `Communicator.send()`도 계획의 `++nonce` 대신 `nextNonce()`를 사용했다.
|
|
- 기존 테스트 수가 계획 작성 시점보다 늘어 `communicator_test.dart`는 8개, 전체 `dart test`는 45개가 실행되었다.
|
|
|
|
## 주요 설계 결정
|
|
|
|
- `initialize()`는 항상 명시적인 `Transport`를 받도록 유지하고, 레거시 fallback transport를 제거했다.
|
|
- `Communicator.send()` 기본 구현은 `queuePacket()`을 통해 동일한 직렬화 경로를 사용한다.
|
|
- `HeartbeatMixin.send()` 오버라이드는 전송 실패 시 `close()`하는 기존 동작을 보존했다.
|
|
|
|
## 리뷰어를 위한 체크포인트
|
|
|
|
- `dart/lib/src/communicator.dart` — `@Deprecated transmitPacket` 메서드 삭제 여부
|
|
- `dart/lib/src/communicator.dart` — `_LegacyCommunicatorTransport` 클래스 삭제 여부
|
|
- `dart/lib/src/communicator.dart` — `initialize()` `transport` 파라미터가 `required`인지
|
|
- `dart/lib/src/communicator.dart` — `send<T>()` 메서드가 concrete이고 `abstract` 키워드가 없는지
|
|
- `dart/lib/src/communicator.dart` — `HeartbeatMixin.send()` `@override`가 여전히 유효한지 (heartbeat_mixin.dart 확인)
|
|
- `dart/test/communicator_test.dart` — `_FakeCommunicator.send()` 오버라이드 삭제 여부
|
|
- `dart analyze` No issues / `dart test` 45개 PASS
|
|
|
|
## 검증 결과
|
|
|
|
### REFACTOR-1 중간 검증
|
|
```
|
|
$ cd dart && dart analyze lib/src/communicator.dart
|
|
Analyzing communicator.dart...
|
|
No issues found!
|
|
```
|
|
|
|
### REFACTOR-2 중간 검증
|
|
```
|
|
$ 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 sendRequest가 timeout 내 응답 없으면 TimeoutException을 던진다
|
|
00:00 +3: Communicator protocol guards nonce wraps after int32 max without emitting zero
|
|
00:00 +4: Communicator protocol guards sendRequest matches response at nonce wrap boundary
|
|
00:00 +5: Communicator protocol guards cannot register addRequestListener for a type already using addListener
|
|
00:00 +6: Communicator protocol guards cannot register addListener for a type already using addRequestListener
|
|
00:00 +7: Communicator protocol guards queuePacket uses injected transport
|
|
00:00 +8: All tests passed!
|
|
```
|
|
|
|
### 최종 검증
|
|
```
|
|
$ cd dart && dart analyze
|
|
Analyzing dart...
|
|
No issues found!
|
|
|
|
$ cd dart && dart test
|
|
00:00 +0: loading test/communicator_test.dart
|
|
00:00 +0: test/communicator_test.dart: Communicator protocol guards response typeName mismatch completes sendRequest with error
|
|
00:00 +1: test/communicator_test.dart: Communicator protocol guards close 후 sendRequest는 StateError로 완료된다
|
|
00:00 +2: test/communicator_test.dart: Communicator protocol guards sendRequest가 timeout 내 응답 없으면 TimeoutException을 던진다
|
|
00:00 +3: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +4: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +5: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +6: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +7: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +8: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
|
|
00:00 +9: test/socket_test.dart: ProtobufClient (plain) 클라이언트가 서버에 연결된다
|
|
00:00 +10: test/socket_test.dart: ProtobufClient (plain) TestData 메시지를 서버가 수신한다
|
|
00:00 +11: test/socket_test.dart: ProtobufClient (plain) 여러 메시지를 순서대로 수신한다
|
|
00:01 +12: test/socket_test.dart: ProtobufClient (plain) 서버에서 클라이언트로 메시지를 전송한다
|
|
00:01 +13: test/socket_test.dart: ProtobufClient (plain) nonce가 송신마다 증가한다
|
|
00:01 +14: test/socket_test.dart: ProtobufClient (plain) 클라이언트 disconnect 시 서버 콜백이 호출된다
|
|
00:02 +15: test/socket_test.dart: ProtobufClient (plain) 서버 stop 시 클라이언트 disconnect 콜백이 호출된다
|
|
00:02 +16: test/socket_test.dart: ProtobufClient (plain) HeartBeat interval 동안 연결이 유지된다
|
|
00:04 +17: test/socket_test.dart: ProtobufClient (plain) close 후 isAlive가 false다
|
|
00:05 +18: test/socket_test.dart: ProtobufClient (plain) 서버가 모든 클라이언트에게 브로드캐스트한다
|
|
00:05 +19: test/socket_test.dart: ProtobufClient (plain) close 후 send는 무시된다
|
|
00:05 +20: test/socket_test.dart: ProtobufClient (plain) TCP closes on oversized packet length
|
|
00:06 +21: test/socket_test.dart: Heartbeat timeout TCP heartbeat 타임아웃 시 disconnect 콜백이 호출된다
|
|
00:08 +22: test/socket_test.dart: Heartbeat timeout WS heartbeat 타임아웃 시 disconnect 콜백이 호출된다
|
|
00:10 +23: test/socket_test.dart: ProtobufServer (SSL) SSL 서버가 정상 시작된다
|
|
00:10 +24: test/socket_test.dart: ProtobufClient (SSL) SSL 클라이언트가 서버에 연결된다
|
|
00:10 +25: test/socket_test.dart: ProtobufClient (SSL) SSL TestData 메시지를 서버가 수신한다
|
|
00:10 +26: test/socket_test.dart: ProtobufClient (SSL) SSL 서버에서 클라이언트로 메시지를 전송한다
|
|
00:11 +27: test/socket_test.dart: ProtobufClient (SSL) SSL disconnect 시 서버 콜백이 호출된다
|
|
00:11 +28: test/socket_test.dart: WsProtobufServer (plain) WS 서버가 정상 시작된다
|
|
00:11 +29: test/socket_test.dart: WsProtobufClient (plain) WS 클라이언트가 서버에 연결된다
|
|
00:11 +30: test/socket_test.dart: WsProtobufClient (plain) WS TestData 메시지를 서버가 수신한다
|
|
00:11 +31: test/socket_test.dart: WsProtobufClient (plain) WS 서버에서 클라이언트로 메시지를 전송한다
|
|
00:12 +32: test/socket_test.dart: WsProtobufClient (plain) WS 클라이언트 disconnect 시 서버 콜백이 호출된다
|
|
00:12 +33: test/socket_test.dart: WsProtobufClient (plain) WS 서버 stop 시 클라이언트 disconnect 콜백이 호출된다
|
|
00:12 +34: test/socket_test.dart: WsProtobufClient (plain) WS close 후 isAlive가 false다
|
|
00:12 +35: test/socket_test.dart: WsProtobufClient (plain) WS 서버가 모든 클라이언트에게 브로드캐스트한다
|
|
00:13 +36: test/socket_test.dart: WsProtobufClient (plain) WS close 후 send는 무시된다
|
|
00:13 +37: test/socket_test.dart: WsProtobufServer (SSL) WSS 서버가 정상 시작된다
|
|
00:13 +38: test/socket_test.dart: WsProtobufClient (SSL) WSS 클라이언트가 서버에 연결된다
|
|
00:13 +39: test/socket_test.dart: WsProtobufClient (SSL) WSS TestData 메시지를 서버가 수신한다
|
|
00:14 +40: test/socket_test.dart: WsProtobufClient (SSL) WSS disconnect 시 서버 콜백이 호출된다
|
|
00:14 +41: test/socket_test.dart: Request-Response (TCP plain) sendRequest로 서버 응답을 받는다
|
|
00:14 +42: test/socket_test.dart: Request-Response (TCP plain) 여러 sendRequest가 각각 올바른 응답을 받는다
|
|
00:14 +43: test/socket_test.dart: Request-Response (WS plain) WS sendRequest로 서버 응답을 받는다
|
|
00:15 +44: test/socket_test.dart: Request-Response (WS plain) WS 여러 sendRequest가 각각 올바른 응답을 받는다
|
|
00:15 +45: All tests passed!
|
|
```
|