작은 WS frame을 isolate 왕복 없이 처리해 full 성능 검증에서 확인된 Dart WS burst hard-gate 회귀를 닫는다. 성능 검증 루프의 task archive와 로드맵 완료 근거도 함께 보존한다.
258 lines
59 KiB
Markdown
258 lines
59 KiB
Markdown
# 언어별 성능 병목 개선
|
|
|
|
## 목표
|
|
|
|
`고성능 병렬 운용 기준선과 최적화` Milestone에서 확보한 stress/performance 측정 결과를 근거로, 안정성 hard gate를 유지하면서 언어별 주요 성능 병목을 줄인다. 우선순위는 같은 local idle baseline에서 반복 재현되는 p99 latency, throughput, memory/backlog 비용이 큰 경로를 기준으로 정한다.
|
|
|
|
## 단계
|
|
|
|
안정화와 유지
|
|
|
|
## 상태
|
|
|
|
[계획]
|
|
|
|
## 구현 잠금
|
|
|
|
- 상태: 해제
|
|
- 결정 필요: 없음
|
|
|
|
## 범위
|
|
|
|
- Dart TCP 경로의 40ms대 고정 지연, burst/sustained 처리량 저하, 1MB payload p99/throughput 병목, buffer copy, per-packet flush, heartbeat timer churn을 분석하고 개선한다.
|
|
- Dart isolate receive gateway는 현재 테스트 가능한 보조 구현 수준이므로 실제 TCP/WS transport 수신 경로 hardening 대상으로 격상한다. `../dart-app-core`의 isolate manager를 그대로 가져오지 않는다면, proto-socket 자체 구현이 backpressure, ordered error, large payload transfer, lifecycle cleanup, 계측 기준에서 동등 이상임을 증명해야 한다.
|
|
- TypeScript WS large payload 경로의 p99 latency와 throughput 병목을 분석하고 개선한다.
|
|
- Kotlin WS roundtrip/payload 경로의 40ms대 지연 패턴과 frame/queue 처리 비용을 분석하고 개선한다.
|
|
- Kotlin TCP 경로는 현재 기준에서 큰 최적화 대상이 아니라 기준선 유지 대상으로 둔다. Kotlin 작업은 WS 고정 지연, slow-mix 검증 모델, large payload JVM heap peak 관찰로 좁힌다.
|
|
- TypeScript gateway 경로가 실제 TCP/WS transport에서 큰 손해를 보이는 원인을 정리한다. 이 작업은 TypeScript에 한정하며, 현재 `worker_threads` 기반 per-frame offload를 제품 기본 경로에서 제거하거나 재설계해 순차 보장과 event loop 보호를 단일 mandatory receive path로 유지한다.
|
|
- Go는 현 측정 기준에서 최우선 성능 최적화 대상이 아니라 reference fast path로 둔다. Go 작업은 slow-mix 검증 모델과 sustained memory 측정 방식 보정처럼 기준점 신뢰도를 높이는 범위로 제한한다.
|
|
- Python은 현 측정 기준에서 최우선 런타임 최적화 대상은 아니지만, reference fast path 보조 기준으로 삼아 다른 언어의 병목 후보와 비교한다. Python 작업은 고동시성 p99 기준점, sustained memory 측정 방식, gateway 관련 API 정책처럼 기준점 신뢰도와 제품 일관성을 높이는 범위로 제한한다.
|
|
- 개선 전후 같은 host/runtime/profile에서 `run_performance.sh` baseline 비교를 수행하고, 전체 cross-lang compatibility matrix로 프로토콜 호환성을 재확인한다.
|
|
|
|
## 기능
|
|
|
|
### Epic: [baseline] 재현 가능한 기준점 확정
|
|
|
|
idle 상태에서 성능 기준점을 다시 찍고, 개선 전후 비교 기준으로 사용할 baseline record를 고른다.
|
|
|
|
- [x] [idle-full] idle host에서 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_performance.sh --full`을 실행해 개선 전 full baseline을 남긴다. 검증: 결과 파일이 same-language, cross-language, TypeScript gateway 구성요소와 `regression_result: SKIPPED`를 기록하고, TypeScript transient 및 Kotlin TCP parallel>=128 deferred(INCOMPLETE) 수용 결정이 완료 로그에 남는다.
|
|
- [x] [compare-rule] baseline 비교는 같은 host/runtime/profile의 `proto-socket-performance-*` 기록끼리만 수행한다. 검증: `run_performance.sh --full --baseline <baseline>` 실행 결과가 compared rows와 regression WARN rows를 기록한다. (evidence: `agent-test/runs/20260605-115943-proto-socket-performance-full.md`가 compared rows: 336, warning rows: 10, regression_result: WARN 기록함)
|
|
|
|
### Epic: [hotspot] 병목 리포트
|
|
|
|
기존 결과와 idle baseline을 비교해 언어별 병목 우선순위를 확정한다.
|
|
|
|
- [x] [hotspot-report] Dart TCP fixed latency/large payload/isolate gateway hardening, TypeScript WS large payload, Kotlin WS latency/slow-mix 검증 모델, TypeScript gateway overhead를 병목 리포트로 정리한다. 검증: 각 병목 후보에 근거 결과 파일, 대상 row, p99/throughput/memory 수치, 개선 전 기준값이 기록된다.
|
|
- [x] [fast-path-ref] Go/Python 결과를 reference fast path로 정리해 다른 언어 경로와 비교한다. 검증: Go/Python concurrency 256 및 1MB payload rows가 같은 표에 포함되고, Go/Python은 최우선 런타임 최적화 대상이 아니라 기준점 보강 대상으로 분류된다.
|
|
|
|
### Epic: [go-reference] Go reference 기준점 보강
|
|
|
|
Go는 현재 측정에서 가장 빠르고 안정적인 구현이므로 병목 최적화 대상이 아니라 비교 기준으로 유지한다. 남은 작업은 제품 구현 변경보다 검증 모델과 측정 artifact 제거에 둔다.
|
|
|
|
- [x] [go-slow-mix-model] Go slow-mix deferred 축을 제품 결함으로 단정하지 않고, public request API의 goroutine scheduling 의존 completion order를 어떻게 검증할지 모델을 정리한다. 검증: `agent-test/runs/20260603-035342-proto-socket-stress-quick.md`의 Go deferred 사유가 병목 리포트에 반영되고, 필요한 경우 결정론적 검증 helper 또는 별도 row 기준이 제안된다. (evidence: Go slow-mix는 concurrent `SendRequestTyped` completion order가 goroutine scheduling에 의존해 public API로 same-connection slow/fast response-arrival order를 결정론적으로 검증할 수 없는 축으로 분리했다. 후속 기준은 public API completion order가 아니라 sequential same-client row 또는 내부 observer/helper가 per-connection FIFO를 직접 관찰하는 별도 row로 둔다.)
|
|
- [x] [go-sustained-memory-metric] Go 30분 sustained memory peak 증가가 구현 leak인지 bench artifact인지 분리한다. 검증: latency 샘플 누적을 streaming percentile 또는 bounded sampling으로 바꿀 필요가 있는지 정리하고, `agent-test/runs/20260602-232000-proto-socket-stress-full.md`의 Go sustained 30초/5분/30분 memory rows가 재해석된다. (evidence: `go/bench/stress.go` sustained profile에 deterministic bounded reservoir sampling(`maxSustainedLatencySamples=100000`)과 `summarizeWithCount`를 적용해 request count/throughput은 전체 성공 request count로 유지하고 p50/p95/p99만 bounded sample snapshot으로 계산하도록 분리했다. `agent-task/archive/2026/06/m-performance-hotspot-optimization/05+04_go_sustained_memory_metric/complete.log` PASS, `agent-test/runs/20260605-195820-proto-socket-stress-quick.md` Go TCP sustained stability violation 0 PASS, `agent-test/runs/20260605-194011-proto-socket-performance-quick.md` Go TCP/WS sustained rows stability violation 0 PASS.)
|
|
- [x] [go-reference-guard] Go는 idle full baseline에서 안정성 hard gate와 reference 수치를 유지하는지 확인한다. 검증: Go TCP/WS concurrency 256, 1MB payload, burst 100k, parallel 1024, sustained rows가 병목 리포트의 reference table에 남고 regression WARN이 있으면 원인을 분리한다. (evidence: `agent-test/runs/20260605-115943-proto-socket-performance-full.md`의 Go TCP/WS c256, 1MB payload, burst 100k, parallel 1024, sustained rows는 stability violation 0 PASS다. regression WARN은 Go WS c16 p99 0.247ms->0.375ms와 Go WS sustained 30분 p99 0.445ms->0.588ms의 sub-ms 상대 변화로 분리했고, throughput hard threshold는 넘지 않아 reference watchlist로 둔다.)
|
|
|
|
### Epic: [python-reference] Python reference 기준점 보강
|
|
|
|
Python은 현재 측정에서 slow-mix와 same-language 안정성 hard gate를 통과한 중간 reference 구현이다. 남은 작업은 큰 런타임 최적화보다 고동시성 p99, sustained memory 측정 artifact, gateway 관련 API 정책을 정리하는 데 둔다.
|
|
|
|
- [x] [python-high-parallel-p99] Python TCP parallel 128/512/1024 clients에서 p99 latency가 커지는 구간을 기준점으로 정리한다. 검증: `agent-test/runs/20260602-232000-proto-socket-stress-full.md`의 Python parallel rows가 병목 리포트에 기록되고, stability violation 0인 correctness 결과와 고동시성 p99 비용이 분리된다. (evidence: Python TCP parallel 128/512/1024 rows는 p99 **93.378ms / 501.368ms / 1288.999ms**, throughput **11350.8 / 8110.3 / 6028.1 rps**이고 timeout/nonce/type/FIFO/pending leak 모두 0으로 PASS다. 따라서 correctness hard gate 통과와 고동시성 p99 비용을 분리해 reference watchlist로 둔다.)
|
|
- [x] [python-sustained-memory-metric] Python 30분 sustained memory peak 증가가 구현 leak인지 bench artifact인지 분리한다. 검증: 30초/5분/30분 memory rows가 latency sample 누적, Python 객체 allocation, asyncio task/queue 잔여 상태 중 어느 후보에 가까운지 재해석된다. (evidence: `python/bench/stress.py` sustained profile에 deterministic bounded reservoir sampling(`SUSTAINED_MAX_LATENCY_SAMPLES=100000`)과 `summarize(..., request_count=...)`를 적용해 request count/throughput은 전체 성공 request count로 유지하고 p50/p95/p99만 bounded sample snapshot으로 계산하도록 분리했다. `agent-task/archive/2026/06/m-performance-hotspot-optimization/06_python_sustained_memory_metric/complete.log` PASS, `agent-test/runs/20260605-213522-proto-socket-performance-quick.md` quick performance same-language/cross-language/TypeScript gateway PASS, `cd python && python3 -m pytest -q` 43 passed.)
|
|
- [x] [python-gateway-api-policy] Python `gateway_type`, `payload_size_threshold`, `process/asyncio` gateway 경로가 제품 정책상 사용자/운영 옵션인지 내부 검증 경로인지 정리한다. 검증: 기본 클라이언트 경로가 단일 검증 경로로 유지되는지 확인하고, 외부 옵션으로 품질 일관성을 깨는 API가 필요하면 제거 또는 내부화 후보로 기록된다. (evidence: `TcpClient`/`WsClient`는 `communicator.initialize(self, parser_map)`만 호출해 기본 client path를 gateway off 단일 경로로 유지한다. Python README와 connect API에는 gateway 옵션이 없고, `python/bench/stress.py`는 gateway profile을 TypeScript-specific으로 SKIP한다. `Communicator.initialize(..., gateway_type, payload_size_threshold)`와 관련 tests는 저수준 내부 검증 경로로만 남기며, 별도 API hardening 작업이 열리면 내부화 후보로 둔다.)
|
|
- [x] [python-reference-guard] Python은 idle full baseline에서 안정성 hard gate와 중간 reference 수치를 유지하는지 확인한다. 검증: Python TCP/WS concurrency 256, 1MB payload, slow-mix, parallel 1024, sustained rows가 병목 리포트의 reference table에 남고 regression WARN이 있으면 원인을 분리한다. (evidence: `agent-test/runs/20260605-115943-proto-socket-performance-full.md`의 Python TCP/WS concurrency 256, 1MB payload, parallel 1024, sustained rows는 stability violation 0 PASS다. Python same-language regression WARN은 WS concurrency=1 p99 **0.258ms -> 0.495ms** 1건뿐이며, sub-ms 상대 변화로 reference watchlist에 둔다. Python cross-language rows도 모두 PASS다.)
|
|
|
|
### Epic: [payload] large payload 최적화
|
|
|
|
큰 payload에서 두드러지는 지연과 처리량 저하를 줄인다.
|
|
|
|
- [x] [dart-tcp-1mb] Dart TCP 1MB payload 경로를 분석하고 p99 latency 또는 throughput을 개선한다. 검증: 같은 idle baseline 대비 Dart TCP `payload=1MB` row가 stability hard gate를 유지하고 p99 또는 throughput이 개선되거나 병목 원인이 명확히 문서화된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/07_dart_tcp_1mb_payload/complete.log` PASS, `agent-test/runs/20260605-225539-proto-socket-stress-full.md` Dart TCP 1MB row throughput **63.2 rps**, p99 **117.646ms**, stability counters 0.)
|
|
- [x] [ts-ws-1mb] TypeScript WS 1MB payload 경로를 분석하고 p99 latency 또는 throughput을 개선한다. 검증: 같은 idle baseline 대비 TypeScript WS `payload=1MB` row가 stability hard gate를 유지하고 p99 또는 throughput이 개선되거나 병목 원인이 명확히 문서화된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/08_ts_ws_1mb_payload/complete.log` PASS, `agent-test/runs/20260606-023554-proto-socket-stress-full.md` TypeScript WS 1MB row throughput **31.6 rps**, p99 **255.039ms**, memory **162.5MB**, stability counters 0. p99/throughput은 개선되지 않았고 남은 병목을 `maskPayload` JS XOR loop, protobuf encode/decode, `parseQueue` 직렬 처리로 문서화했다.)
|
|
|
|
### Epic: [dart-tcp] Dart TCP 및 isolate receive path hardening
|
|
|
|
Dart는 WS small roundtrip은 양호하지만 TCP roundtrip/payload/burst/sustained에서 40ms대 고정 지연, 처리량 저하, 1MB payload 병목이 반복된다. 현재 `IsolateInboundGateway`는 단위 테스트로는 동작하지만 실제 `ProtobufClient`/`WsProtobufClient` transport 수신 경로에 연결되어 있지 않으므로, TCP write/read path 개선과 isolate receive gateway 제품화 조건을 함께 다룬다.
|
|
|
|
- [x] [dart-tcp-fixed-latency] Dart TCP 40ms대 고정 지연 원인을 분리한다. 검증: `tcpNoDelay` 부재, per-packet `flush()`, write serialization, heartbeat timer churn, stream pause/resume 중 어느 후보가 TCP concurrency 16/64/256 및 sustained p99를 만드는지 같은 idle baseline에서 기록된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/09_dart_tcp_latency_heartbeat/complete.log` PASS, `agent-test/runs/20260606-031314-proto-socket-stress-quick.md`, `agent-test/runs/20260606-031336-proto-socket-performance-quick.md`.)
|
|
- [x] [dart-tcp-burst-sustained] Dart TCP burst/sustained 처리량 저하를 fixed-latency 분석과 함께 분리한다. 검증: `agent-test/runs/20260602-232000-proto-socket-stress-full.md`의 Dart TCP burst 100k throughput 및 sustained 30분 throughput/p99 rows가 개선 전 기준으로 기록되고, write flush, heartbeat timer churn, receive buffering 중 원인 후보가 구분된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/09_dart_tcp_latency_heartbeat/complete.log` PASS, `agent-test/runs/20260606-031314-proto-socket-stress-quick.md`, `agent-test/runs/20260606-031336-proto-socket-performance-quick.md`.)
|
|
- [x] [dart-tcp-buffer-copy] Dart TCP large payload의 write/read buffer copy를 줄인다. 검증: `_socket.add([...header, ...baseBytes])`, `_arrivedData.sublist`, `Uint8List.fromList`, `List<int>.from` 비용이 개선 전후로 비교되고, TCP 64KB/1MB payload row의 p99 또는 throughput이 개선되거나 남은 병목이 문서화된다. (evidence: `dart/lib/src/protobuf_client.dart`에서 `_TcpFrameBuffer`로 `_arrivedData.sublist`/`Uint8List.fromList`/`List<int>.from` 기반 누적 copy를 제거하고 `_socket.add(header)` + `_socket.add(baseBytes)` split write로 `[...]` 결합 copy를 제거했다. `cd dart && dart test test/socket_test.dart -r expanded` 40 passed, `cd dart && dart test test/communicator_test.dart -r expanded` 21 passed. `agent-test/runs/20260606-030400-proto-socket-stress-quick.md` Dart TCP payload 64KB row throughput **1273.6 rps**, p99 **3.096ms**, stability counters 0 PASS. 1MB row는 `agent-test/runs/20260605-225539-proto-socket-stress-full.md`에서 throughput **63.2 rps**, p99 **117.646ms**, stability counters 0으로 기존 9.6 rps/892.819ms 대비 개선됐다. per-packet `flush()`와 heartbeat 고정 지연 후보는 [dart-tcp-fixed-latency]/[dart-heartbeat-cost]로 유지한다.)
|
|
- [x] [dart-heartbeat-cost] Dart heartbeat timer churn을 성능 경로에서 분리한다. 검증: frame 수신마다 `sendHeartBeat()`가 timer를 cancel/recreate하는 비용을 계측하고, interval 0이 비활성화가 아닌 즉시 발화로 동작하는 현재 semantics가 테스트 표준과 제품 정책에서 정리된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/09_dart_tcp_latency_heartbeat/complete.log` PASS, `cd dart && dart test test/socket_test.dart -r expanded`, `agent-test/runs/20260606-031314-proto-socket-stress-quick.md`.)
|
|
- [x] [dart-isolate-equal-or-better] `../dart-app-core` isolate manager를 가져오지 않는 결정이 타당한지 비교 기준을 작성한다. 검증: 현재 proto-socket `IsolateInboundGateway`가 `dart-app-core`의 long-running isolate, ready/exit event, message routing, lifecycle 관리 수준 대비 어떤 장단점이 있는지 기록하고, 독자 구현을 유지한다면 동등 이상 조건이 명시된다. (evidence: `../dart-app-core/lib/platform/isolate_manager.dart`는 `IsolateManager.create`/`IsolateBase`/`IsoMessege` 기반 long-running isolate, ready/exit event, string message routing, broadcast, manager map cleanup을 제공한다. proto-socket `IsolateInboundGateway`는 protocol-specific long-running worker, ready completer, `FrameReorderBuffer` seq ordering, pure `PacketBase` decode, `SyncInboundGateway` web fallback, close 시 isolate/ReceivePort/result stream 정리를 제공해 wire FIFO/nonce dispatch 책임에는 더 직접적이다. 후속 `agent-task/archive/2026/06/m-performance-hotspot-optimization/10_dart_isolate_gateway_contract/complete.log`, `11+10_dart_isolate_transport_path/complete.log`, `12+10,11_dart_isolate_large_payload/complete.log` PASS로 실제 TCP/WS transport 연결, bounded backpressure/backlog metrics, ordered decode error, `TransferableTypedData` large payload transfer, repeated cleanup hard gate 조건을 충족했다.)
|
|
- [x] [dart-isolate-real-path] Dart isolate receive gateway를 실제 TCP/WS transport 수신 경로 hardening 대상으로 연결한다. 검증: 테스트 전용 `attachInboundGateway`에 머물지 않고 제품 내부 단일 수신 경로에서 FIFO, nonce matching, close cleanup, web fallback을 유지하며, 사용자/운영 on-off 옵션 없이 성능 row에 반영된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/11+10_dart_isolate_transport_path/complete.log` PASS, `dart test test/socket_test.dart test/communicator_test.dart -r expanded`, `dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js`, `agent-test/runs/20260606-045133-proto-socket-stress-quick.md`, `agent-test/runs/20260606-045148-proto-socket-performance-quick.md`.)
|
|
- [x] [dart-isolate-backpressure] Dart isolate gateway에 bounded backpressure와 backlog 계측을 추가한다. 검증: `SendPort.send()` 무제한 mailbox 의존을 제거하거나 제한 조건을 문서화하고, queued/in-flight/reorder/sink residual backlog가 stress/performance 결과에 기록된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/10_dart_isolate_gateway_contract/complete.log` PASS, `dart test test/communicator_test.dart -r expanded`, `dart test`, `dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js`.)
|
|
- [x] [dart-isolate-error-ordering] Dart isolate gateway decode error를 입력 순서대로 보고하고 transport disconnect semantics와 연결한다. 검증: malformed frame이 isolate를 죽이거나 reorder를 영구 대기시키지 않고, ordered error result, close, pending cleanup 테스트가 추가된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/10_dart_isolate_gateway_contract/complete.log` PASS, `dart test test/communicator_test.dart -r expanded`, `dart test`.)
|
|
- [x] [dart-isolate-large-payload-transfer] Dart isolate gateway의 large payload 전달 비용을 줄인다. 검증: 1MB frame에서 isolate message copy 비용을 `TransferableTypedData` 또는 동등한 최소-copy 방식으로 줄일 수 있는지 확인하고, 적용 전후 TCP/WS 1MB payload p99/throughput과 memory row가 기록된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/12+10,11_dart_isolate_large_payload/complete.log` PASS, `dart test test/communicator_test.dart -r expanded`, `dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile_review.js`, `agent-test/runs/20260606-050440-proto-socket-stress-full.md`, `agent-test/runs/20260606-050449-proto-socket-performance-quick.md`.)
|
|
- [x] [dart-isolate-cleanup] Dart isolate gateway lifecycle cleanup을 hard gate로 만든다. 검증: close 후 isolate, ReceivePort, SendPort, result stream, reorder buffer, pending queue가 잔여 없이 정리되고 repeated run memory/backlog 증가가 0으로 기록된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/10_dart_isolate_gateway_contract/complete.log` PASS, `dart test test/communicator_test.dart -r expanded`, `dart test`.)
|
|
|
|
### Epic: [ws-latency] Kotlin WS 지연 및 검증 모델 개선
|
|
|
|
Kotlin TCP는 현재 same-language 기준에서 안정적인 유지 대상이다. Kotlin 개선은 WS roundtrip/payload의 40ms대 고정 지연 패턴을 줄이고, slow-mix 검증 모델을 보정하되 FIFO와 nonce matching 계약을 깨지 않는 데 둔다.
|
|
|
|
- [x] [kotlin-ws-delay] Kotlin WS roundtrip/payload 경로의 고정 지연을 분석하고 병목을 줄인다. 검증: OkHttp callback, `ByteString.toByteArray()` copy, `receiveQueue` Channel staging, communicator inbound queue, write/send flush 비용이 분리되고, Kotlin WS roundtrip concurrency 16/64/256 및 1KB/64KB/1MB payload rows가 stability hard gate를 유지한 채 p99 또는 throughput이 개선되거나 병목 원인이 명확히 문서화된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/14+13_kotlin_ws_transport_hardening/complete.log` PASS. `WsServer.onConnect`에서 accepted socket `TCP_NODELAY`를 적용했고, OkHttp WS send path는 `Buffer().write(bytes).readByteString()`로 Kotlin vararg spread-copy를 제거했다. WS receive staging은 13번 diagnostics와 focused stress의 `wsDropped=0`, backlog leak 0 근거로 유지했다. 검증은 `cd kotlin && ./gradlew test`, `run_stress.sh --quick --lang kotlin --transport tcp,ws --profile roundtrip,payload` 결과 `agent-test/runs/20260606-121117-proto-socket-stress-quick.md` PASS, `run_performance.sh --quick` 결과 `agent-test/runs/20260606-121129-proto-socket-performance-quick.md` PASS.)
|
|
- [x] [kotlin-slow-mix-model] Kotlin slow-mix deferred 축을 제품 결함으로 단정하지 않고, 같은 client의 concurrent request completion order가 coroutine scheduling에 의존하는 검증 모델을 보정한다. 검증: 결정론적 helper, sequential same-client row, 또는 per-connection FIFO를 직접 관찰하는 별도 row 중 하나가 제안되고, `agent-test/runs/20260603-035352-proto-socket-stress-quick.md`의 Kotlin deferred 사유가 병목 리포트에 반영된다. (evidence: `kotlin/crosstest/stress.kt`의 `deferredBottleneck`은 slow-mix를 같은 client concurrent request completion order가 coroutine scheduling에 의존하는 축으로 분리한다. 후속 검증 모델은 public concurrent completion order가 아니라 sequential same-client row 또는 내부 observer/helper가 per-connection FIFO를 직접 관찰하는 별도 row로 둔다. `agent-test/runs/20260603-035352-proto-socket-stress-quick.md`의 Kotlin TCP/WS slow-mix INCOMPLETE는 stability violation 0, required SKIP 2로 남겨 제품 결함 PASS/FAIL로 단정하지 않는다.)
|
|
- [x] [kotlin-large-payload-memory] Kotlin large payload heap peak를 WS 지연 개선과 함께 관찰한다. 검증: `agent-test/runs/20260603-062724-proto-socket-stress-full.md`의 Kotlin TCP/WS 1MB payload memory rows가 개선 전 기준으로 기록되고, JVM allocation/GC 영향과 실제 queue/backlog 잔여 상태가 분리된다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/complete.log` PASS. Kotlin focused full stress `agent-test/runs/20260606-184707-proto-socket-stress-full.md`에서 WS 1MB row throughput **111.1 rps**, p99 **77.759ms**, memory **475.5MB**, queueBacklog **1**, `wsDropped=0`, stability violations 0을 기록했다. 기존 `20260603-062724` WS 1MB 기준 throughput **84.2 rps**, p99 **133.842ms**, memory **668.3MB** 대비 heap peak와 latency/throughput이 함께 개선됐고, reviewer rerun `agent-test/runs/20260606-192408-proto-socket-performance-quick.md`도 PASS다.)
|
|
- [x] [kotlin-tcp-reference-guard] Kotlin TCP는 idle full baseline에서 현재 기준선이 유지되는지 확인한다. 검증: Kotlin TCP concurrency 256 및 TCP 1MB payload rows가 reference table에 남고, WS 개선 작업이 TCP p99/throughput 또는 stability hard gate를 악화시키지 않는다. (evidence: `agent-task/archive/2026/06/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/complete.log` PASS. Kotlin focused full stress `agent-test/runs/20260606-184707-proto-socket-stress-full.md`에서 TCP c256 throughput **17691.5 rps**, p99 **18.903ms**, queueBacklog 0, stability violations 0을 기록했다. TCP 1MB row는 throughput **407.5 rps**, p99 **28.574ms**, memory **358.0MB**, queueBacklog 0, stability violations 0이며, WS 개선 작업이 TCP hard gate를 깨지 않았음을 확인했다. reviewer rerun `agent-test/runs/20260606-192408-proto-socket-performance-quick.md`도 PASS다.)
|
|
|
|
### Epic: [gateway] TypeScript gateway 단일 수신 경로
|
|
|
|
이 Epic은 TypeScript gateway에 한정한다. gateway는 순차 이벤트 보장과 event loop 보호를 담당하는 mandatory receive path이며, 사용자/운영 설정으로 켜고 끄는 옵션을 두지 않는다. 현재 `worker_threads` per-frame offload 비용은 gateway를 끄는 근거가 아니라, worker hop을 기본 경로에서 제거하거나 내부 구현으로 재설계해야 하는 hardening 근거로 분류한다.
|
|
|
|
- [x] [ts-gateway-single-path] TypeScript gateway를 제품 기본 수신 경로로 유지하기 위한 단일 경로 조건을 정의한다. 검증: gateway가 FIFO, nonce matching, close cleanup, bounded backlog hard gate를 유지하고, gateway/worker on-off 같은 외부 옵션 없이 같은 idle baseline 대비 p99/throughput 회귀 기준을 넘지 않는 조건이 문서화된다.
|
|
- [x] [ts-worker-hop-removal] TypeScript `worker_threads` 기반 per-frame offload를 기본 gateway 경로에서 제거하거나, 동일 단일 경로 내부 구현으로 재설계한다. 검증: worker hop, buffer copy, reorder wait, sink serialization, backpressure 차이, memory 증가, p99 악화 원인이 줄어들고, 결과가 `run_performance.sh --full --baseline <baseline>` 병목 리포트에 기록된다.
|
|
- [x] [gateway-overhead] TypeScript gateway 경로의 남은 overhead를 legacy inline control row와 비교해 정량화한다. 검증: 차이가 제품 정책 옵션으로 해석되지 않도록 control row는 분석용 대조군으로만 기록되고, 결론은 단일 mandatory receive path hardening 항목으로 남는다.
|
|
|
|
### Epic: [verify] 회귀 검증
|
|
|
|
개선 후 안정성과 호환성 회귀가 없는지 확인한다.
|
|
|
|
- [ ] [perf-regression] 개선 후 `run_performance.sh --full --baseline <baseline>`을 실행해 throughput 20% 이상 하락 또는 p99 25% 이상 악화 WARN 후보를 확인한다. 검증: regression WARN row가 없거나, 남은 WARN row의 원인과 후속 처리가 기록된다.
|
|
- [ ] [compat-matrix] 개선 후 `bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all`을 실행한다. 검증: Proto sync, 동일언어, Dart.web/Dart.web(WSS), 전체 cross-lang matrix가 PASS다.
|
|
|
|
## 작업 순서
|
|
|
|
현재 host가 느려진 상태에서는 full 성능 측정을 기준값으로 쓰지 않는다. full baseline은 idle host에서만 확정하고, 그 전에는 문서/설계/검증 모델 정리와 harness sanity check만 수행한다.
|
|
|
|
1. 기준점 확정
|
|
- [idle-full], [compare-rule]을 먼저 수행한다.
|
|
- `run_performance.sh --quick`은 harness sanity check 용도로만 사용하고, 병목 우선순위와 개선 전후 판정은 idle host의 `--full` 결과로만 한다.
|
|
- [hotspot-report], [fast-path-ref]에서 언어별 병목과 Go/Python reference 기준점을 한 표로 정리한다.
|
|
2. 신뢰 경로와 검증 모델 정리
|
|
- TypeScript: [ts-gateway-single-path]로 mandatory receive path 조건을 먼저 고정한다.
|
|
- Dart: [dart-isolate-equal-or-better], [dart-isolate-backpressure], [dart-isolate-error-ordering], [dart-isolate-cleanup]으로 isolate gateway 제품화 조건을 먼저 정한다.
|
|
- Go/Kotlin/Python: [go-slow-mix-model], [kotlin-slow-mix-model], [python-gateway-api-policy]처럼 제품 결함과 검증 모델/정책 문제를 분리한다.
|
|
3. 구현 우선순위
|
|
- 1순위: TypeScript [ts-worker-hop-removal]. 순차 보장과 event loop 보호를 유지하면서 worker hop 비용을 제거하거나 재설계한다.
|
|
- 2순위: Dart [dart-tcp-fixed-latency], [dart-tcp-burst-sustained], [dart-tcp-buffer-copy], [dart-heartbeat-cost], [dart-isolate-real-path], [dart-isolate-large-payload-transfer]. TCP 고정 지연과 1MB payload 병목, isolate receive path hardening을 같이 다룬다.
|
|
- 3순위: Kotlin [kotlin-ws-delay], [kotlin-large-payload-memory] 완료. WS 고정 지연과 large payload heap peak를 함께 확인했고, [kotlin-tcp-reference-guard]로 TCP 기준선 보존도 확인했다.
|
|
- 4순위: TypeScript [ts-ws-1mb]. gateway 단일 경로가 안정된 뒤 WS large payload를 개선한다.
|
|
- 5순위: Go/Python reference guard와 memory metric 보강. 최적화보다 측정 artifact와 회귀 감시에 둔다.
|
|
4. 회귀 검증
|
|
- 각 구현 묶음 후 [perf-regression]으로 같은 idle baseline 대비 회귀를 확인한다.
|
|
- 마지막에는 [compat-matrix]로 전체 cross-language compatibility를 재확인한다.
|
|
|
|
## 작업 동기화
|
|
|
|
- 2026-06-03 기준 지원 5개 언어 분석은 완료했다. Go/Python은 reference 기준점 보강, Kotlin은 WS latency/slow-mix 검증 모델, Dart는 TCP fixed latency/large payload/isolate receive path, TypeScript는 gateway worker hop과 WS 1MB가 핵심 작업이다.
|
|
- `고성능 병렬 운용 기준선과 최적화` Milestone의 기준선/매트릭스 결과를 선행 근거로 사용한다.
|
|
- 2026-06-05 기준 `03_idle_full_baseline`은 USER_REVIEW 해소로 PASS/RESOLVED 완료했고, `agent-task/archive/2026/06/m-performance-hotspot-optimization/03_idle_full_baseline/complete.log`가 Roadmap Completion `idle-full`을 남겼다.
|
|
- `05+04_go_sustained_memory_metric`은 archive PASS로 완료됐고, `agent-task/archive/2026/06/m-performance-hotspot-optimization/05+04_go_sustained_memory_metric/complete.log`가 Roadmap Completion `go-sustained-memory-metric`을 남겼다. Go reference 기준점 보강 Epic의 세 Task([go-slow-mix-model], [go-sustained-memory-metric], [go-reference-guard])는 모두 완료 상태다.
|
|
- Python reference 기준점 보강 Epic은 [python-high-parallel-p99], [python-gateway-api-policy], [python-reference-guard]를 기존 stress/performance record와 Python API 확인으로 즉시 완료 처리했다. [python-sustained-memory-metric]은 `agent-task/archive/2026/06/m-performance-hotspot-optimization/06_python_sustained_memory_metric/complete.log`의 PASS 완료 이벤트와 bounded sampling 적용 근거로 완료 처리했다.
|
|
- Payload Epic의 [dart-tcp-1mb]는 `07_dart_tcp_1mb_payload` archive PASS와 Dart TCP targeted full row 개선 근거로 완료 처리했다. 해당 작업은 `_TcpFrameBuffer`와 split TCP write로 buffer copy 비용도 줄였지만, Roadmap Completion에 명시된 완료 Task id는 [dart-tcp-1mb]이므로 [dart-tcp-buffer-copy]는 별도 task로 유지한다.
|
|
- Payload Epic의 [ts-ws-1mb]는 `08_ts_ws_1mb_payload` archive PASS와 TypeScript WS 1MB targeted full row/잔여 병목 문서화 근거로 완료 처리했다. p99/throughput은 개선되지 않았고, completion 근거는 stability 0 유지와 소스 기반 병목 문서화다.
|
|
- 사용자 확인으로 Kotlin TCP parallel>=128 deferred(INCOMPLETE)는 이번 `idle-full` 완료 기준에서 수용됐으며, 해당 deadlock은 별도 최적화 대상으로 유지한다.
|
|
- `13_kotlin_ws_diagnostics`는 2026-06-06 archive PASS로 완료됐다. 이 subtask는 Roadmap Completion Task id를 남기지 않았으므로 기능 Task 체크는 하지 않았고, Kotlin WS diagnostics accessor internal boundary, WSS lifecycle cleanup, focused Kotlin WS stress PASS 근거를 14번 `kotlin-ws-delay` hardening의 선행 조건으로 사용했다. `14+13_kotlin_ws_transport_hardening`은 archive PASS로 완료되어 Roadmap Completion Task id `kotlin-ws-delay`를 닫았다. `15+14_kotlin_ws_reference_guard`도 archive PASS로 완료되어 Roadmap Completion Task ids `kotlin-large-payload-memory`, `kotlin-tcp-reference-guard`를 닫았다. 남은 Milestone 기능 Task는 [perf-regression], [compat-matrix]다.
|
|
|
|
## 완료 리뷰
|
|
|
|
- 상태: 없음
|
|
- 요청일: 없음
|
|
- 완료 근거: 없음
|
|
- 리뷰 필요:
|
|
- [ ] 사용자가 완료 결과를 확인했다
|
|
- [ ] archive 이동을 승인했다
|
|
- 리뷰 코멘트: 없음
|
|
|
|
## 범위 제외
|
|
|
|
- wire format, proto schema, nonce 의미를 변경하지 않는다.
|
|
- 성능 개선을 위해 FIFO, request-response matching, close cleanup 계약을 완화하지 않는다.
|
|
- TypeScript 외 언어에 `worker_threads` 결론을 일반화하지 않는다.
|
|
- gateway on/off, worker on/off 같은 사용자/운영 옵션을 추가하지 않는다.
|
|
- Dart isolate gateway를 테스트 전용 또는 외부 옵션으로만 남겨 성능/신뢰 경로를 우회하지 않는다.
|
|
- Go에 대해 충분한 기준점 없이 런타임 최적화 작업을 새로 시작하지 않는다.
|
|
- Python에 대해 충분한 기준점 없이 런타임 최적화 작업을 새로 시작하지 않는다.
|
|
- Kotlin TCP 경로는 충분한 병목 근거 없이 구조 변경하지 않는다.
|
|
- package registry 릴리즈, 외부 CI/CD runner 연결을 시작하지 않는다.
|
|
- C# 또는 Swift 포팅을 시작하지 않는다.
|
|
- 애플리케이션 레벨 priority queue, routing key, room/session semantics를 추가하지 않는다.
|
|
- 서로 다른 host/runtime/profile의 절대 throughput 수치를 고정 합격선으로 삼지 않는다.
|
|
|
|
## 작업 컨텍스트
|
|
|
|
- 병목 리포트:
|
|
|
|
> [!WARNING]
|
|
> **Full Idle Baseline evidence — 수용된 INCOMPLETE (2026-06-05)**: idle host에서 `run_performance.sh --full` 결과를 수집했다. 측정 host는 code-server 컨테이너이며 load ~6/10코어 상태를 이 환경의 idle 기준으로 인정한다(컨테이너 상시 부하를 차단/감점 사유로 보지 않는다). baseline evidence record: [`agent-test/runs/20260605-025842-proto-socket-performance-full.md`](file:///config/workspace/proto-socket/agent-test/runs/20260605-025842-proto-socket-performance-full.md). 구성요소 record는 same-language [`...025842-...stress-full.md`](file:///config/workspace/proto-socket/agent-test/runs/20260605-025842-proto-socket-stress-full.md), cross-language [`...091449-...stress-full-cross.md`](file:///config/workspace/proto-socket/agent-test/runs/20260605-091449-proto-socket-stress-full-cross.md), typescript-gateway [`...092037-...stress-full.md`](file:///config/workspace/proto-socket/agent-test/runs/20260605-092037-proto-socket-stress-full.md)이다.
|
|
> - 사용자 결정으로 이 record를 `idle-full` 완료 baseline evidence로 수용한다. record에 기록된 최상위 `overall_result`는 **FAIL**, `regression_result`는 `--baseline` 미지정으로 SKIPPED다. 구성요소는 same-language **FAIL**, cross-language PASS, typescript-gateway PASS이며, same-language 내부는 dart/go/python PASS, kotlin INCOMPLETE, typescript FAIL이다.
|
|
> - 구성요소 same-language / cross-language / typescript-gateway 모두 포함. sustained 30초/5분/30분은 5개 언어 TCP/WS 전부 stability violation 0 PASS.
|
|
> - 기록된 FAIL의 단일 원인은 `parallel clients=1024 / TypeScript / tcp` 행의 timeout 72건(512,000 요청 중 0.014%, 그 외 nonce/FIFO/leak violation 0)이다. 2026-06-05 동일 조건 재측정([`agent-test/runs/20260605-100551-proto-socket-stress-full.md`](file:///config/workspace/proto-socket/agent-test/runs/20260605-100551-proto-socket-stress-full.md), `overall_result: PASS`)에서 16/128/512/1024 전부 timeout 0 PASS로 재현되지 않아 일시적 컨테이너 부하 transient로 판정한다. TypeScript TCP 구현의 회귀/병목이 아니다. 다만 이 재측정은 TypeScript focused rerun이므로 full aggregate PASS를 대체하는 근거로 쓰지 않는다.
|
|
> - TypeScript transient를 제외해도 이 record는 PASS가 될 수 없다. Kotlin TcpClient가 연결당 timeout 없는 blocking read-thread-per-connection 구조라 TCP parallel clients>=128에서 thread starvation으로 deadlock하며, 해당 축을 harness에서 deferred(required SKIP)로 처리했다. harness가 required SKIP을 INCOMPLETE로 분류하는 것은 의도된 설계이고 optional 우회로 PASS를 만들지 않는다. 따라서 transient를 걷어낸 본질 상태는 Kotlin deferred로 인한 **INCOMPLETE**다. 이 Kotlin TCP parallel>=128 deadlock은 별도 최적화 대상(Epic)으로 남긴다.
|
|
> - `idle-full`의 원래 완료 기준은 `overall_result: PASS`였지만 Kotlin deadlock(required SKIP→INCOMPLETE, 의도된 설계) 때문에 구조적으로 충족 불가하다. 사용자 결정으로 Kotlin deferred INCOMPLETE를 이번 `idle-full` 완료 기준에서 수용했고, `03_idle_full_baseline`은 `complete.log`의 Roadmap Completion에 따라 PASS/RESOLVED 완료 처리됐다.
|
|
> - 서로 다른 host/runtime/profile의 절대 수치는 고정 합격선으로 삼지 않는다. 이 record는 개선 전후를 같은 환경에서 비교하기 위한 baseline evidence record로만 사용한다.
|
|
|
|
### 1. 언어별 병목 후보 및 개선 목표
|
|
|
|
| 병목 후보 | 근거 파일 / 대상 Row | 개선 전 기준값 (p99 / Throughput / Memory) | 판정 및 병목 의존성 | 후속 Task ID |
|
|
|---|---|---|---|---|
|
|
| **Dart TCP**<br>(Fixed Latency, Burst, Sustained) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- TCP Concurrency 256<br>[stress-full (20260602)](file:///config/workspace/proto-socket/agent-test/runs/20260602-232000-proto-socket-stress-full.md)<br>- TCP Burst 100k<br>- TCP Sustained 30분 | - Concurrency 256 p99: **49.109ms**<br>- Burst 100k: **154.4 rps**<br>- Sustained throughput: **385.3 rps** / p99: **44.079ms** | `tcpNoDelay` 미설정 의심, per-packet `flush()`, write serialization, heartbeat timer churn, stream pause/resume 오버헤드 존재. | `dart-tcp-fixed-latency`<br>`dart-tcp-burst-sustained`<br>`dart-heartbeat-cost` |
|
|
| **Dart TCP 1MB**<br>(Large Payload) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- TCP Payload 1MB | - Throughput: **9.6 rps**<br>- p99: **892.819ms** | 대형 payload 전송 시 write/read buffer copy 비용 극대화. `_socket.add` 및 sublist 비용 최적화 필요. | `dart-tcp-buffer-copy`<br>`dart-tcp-1mb` |
|
|
| **Dart Isolate Gateway**<br>(Path Hardening) | `dart/lib/src/inbound_gateway_io.dart` 및 `test/communicator_test.dart` | - 성능 Matrix 미연결 (테스트 전용) | 현재 수신 gateway가 메인 transport에 연결되어 있지 않음. `dart-app-core` 대비 동등 이상 신뢰성/라이프사이클 확보, `TransferableTypedData` 사용 및 FIFO, backpressure 구현 필요. | `dart-isolate-equal-or-better`<br>`dart-isolate-real-path`<br>`dart-isolate-backpressure`<br>`dart-isolate-error-ordering`<br>`dart-isolate-large-payload-transfer`<br>`dart-isolate-cleanup` |
|
|
| **TypeScript WS 1MB**<br>(Large Payload) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- WS Payload 1MB | - p99: **228.648ms** | 대용량 WebSocket 프레임 전송/수신 처리량 저하 및 지연 병목. | `ts-ws-1mb` |
|
|
| **TypeScript Gateway**<br>(Worker Overhead) | [stress-full (20260603-gateway)](file:///config/workspace/proto-socket/agent-test/runs/20260603-080241-proto-socket-stress-full.md)<br>- Gateway transport=ws concurrency=16<br>- Gateway transport=tcp concurrency=16 | - WS Gateway: **2499.3 rps** (vs Control: **16242.7 rps**)<br>- WS Gateway p99: **205.654ms** (vs Control: **1.887ms**)<br>- TCP Gateway p99: **193.306ms** (vs Control: **43.095ms**) | `worker_threads` 기반 frame offload hop 비용, buffer copy, reorder wait로 인해 심각한 병목 유발. worker hop 제거 또는 단일 수신 경로로 재설계 필수. | `ts-gateway-single-path`<br>`ts-worker-hop-removal`<br>`gateway-overhead` |
|
|
| **Kotlin WS**<br>(Fixed Latency, Large Payload) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- WS Concurrency 256<br>- WS Payload 1KB / 1MB | - Concurrency 256 p99: **44.877ms**<br>- Payload 1KB p99: **42.651ms**<br>- Payload 1MB p99: **133.842ms**<br>- Payload 1MB Heap Peak: **~668.3MB** | OkHttp 콜백, ByteString copy, Channel staging, inbound queue, write/send flush 지연 의심. 대용량 payload 시 JVM allocation/GC 유발 가능성. | `kotlin-ws-delay`<br>`kotlin-large-payload-memory` |
|
|
| **Kotlin slow-mix**<br>(검증 모델 보정) | [stress-quick (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-035352-proto-socket-stress-quick.md)<br>- slow-mix deferred | - 검증 결과: **Deferred** | 같은 client의 concurrent request completion order는 coroutine scheduling에 의존하므로 public API 완료 순서를 per-connection FIFO 결함으로 보지 않는다. 후속 검증은 sequential same-client row 또는 내부 observer/helper가 response-arrival/FIFO를 직접 관찰하는 별도 row로 둔다. | `kotlin-slow-mix-model` |
|
|
|
|
### 2. Reference Fast Path (비교 및 감시 기준)
|
|
|
|
> [!NOTE]
|
|
> Go 및 Python은 최우선 런타임 최적화 대상이 아닙니다. 아래 reference 수치는 타 언어의 성능 개선 시 대조군 및 regression 감시 기준으로만 사용됩니다.
|
|
|
|
| 언어 및 Reference 유형 | 근거 파일 / 대상 Row | 성능 지표 (p99 / Throughput / Memory) | 비고 및 보강 Task | 후속 Task ID |
|
|
|---|---|---|---|---|
|
|
| **Go TCP / WS**<br>(Reference Fast Path) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- TCP Concurrency 256<br>- WS Concurrency 256<br>- TCP Payload 1MB<br>- WS Payload 1MB<br>[stress-full (20260602)](file:///config/workspace/proto-socket/agent-test/runs/20260602-232000-proto-socket-stress-full.md)<br>- TCP Burst 100k<br>- TCP Parallel 1024<br>- TCP Sustained 30분<br>[performance-full (20260605)](file:///config/workspace/proto-socket/agent-test/runs/20260605-115943-proto-socket-performance-full.md)<br>- idle full guard + baseline comparison | - TCP 256: **60748.4 rps** / p99 **4.432ms**<br>- WS 256: **62631.5 rps** / p99 **4.872ms**<br>- 1MB p99: **21.076ms** (TCP) / **35.880ms** (WS)<br>- Burst 100k: **201132.8 rps**<br>- Parallel 1024: **214665.2 rps** / p99 **154.621ms**<br>- Sustained throughput: **16264.9 rps** / p99 **0.646ms**<br>- Sustained Memory (30초/5분/30분): **57.1MB / 143.4MB / 794.1MB** | `go-reference-guard` 완료: idle full guard에서 Go TCP/WS c256, 1MB payload, burst 100k, parallel 1024, sustained rows 모두 stability hard gate 0 PASS. Go regression WARN 2건은 WS sub-ms p99 상대 변화로 분리해 reference watchlist로 둔다. 30분 sustained memory 증가는 기존 harness의 latency sample 무제한 보관 artifact로 분리했고, bounded sampling 적용 후 quick Go TCP/WS sustained rows는 stability violation 0 PASS로 확인했다. | `go-sustained-memory-metric` |
|
|
| **Go slow-mix**<br>(검증 모델 보정) | [stress-quick (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-035342-proto-socket-stress-quick.md)<br>- slow-mix deferred | - 검증 결과: **Deferred** | concurrent `SendRequestTyped` 완료 순서가 goroutine scheduling에 의존해 deferred 발생. 검증 helper/기준 보완. | `go-slow-mix-model` |
|
|
| **Python TCP / WS**<br>(Reference Medium Path) | [stress-full (20260603)](file:///config/workspace/proto-socket/agent-test/runs/20260603-062724-proto-socket-stress-full.md)<br>- TCP Concurrency 256<br>- WS Concurrency 256<br>- TCP Payload 1MB<br>- WS Payload 1MB<br>[stress-full (20260602)](file:///config/workspace/proto-socket/agent-test/runs/20260602-232000-proto-socket-stress-full.md)<br>- TCP Parallel (128/512/1024)<br>- Sustained Memory (30초/5분/30분)<br>[performance-full (20260605)](file:///config/workspace/proto-socket/agent-test/runs/20260605-115943-proto-socket-performance-full.md)<br>- idle full guard + baseline comparison | - TCP 256: **10396.7 rps** / p99 **26.480ms**<br>- WS 256: **7790.6 rps** / p99 **29.769ms**<br>- 1MB p99: **18.856ms** (TCP) / **47.424ms** (WS)<br>- Parallel p99: **93.378ms** (128) / **501.368ms** (512) / **1288.999ms** (1024)<br>- Sustained Memory: **133.8MB / 181.1MB / 614.5MB** | 안정적인 중간 reference. 고동시성 p99 비용은 correctness hard gate PASS와 분리했고, default TCP/WS client API는 gateway off 단일 경로로 유지한다. idle full guard의 Python rows는 stability hard gate 0 PASS이며, Python WARN 1건은 WS c1 sub-ms p99 상대 변화로 watchlist에 둔다. sustained memory 증가는 Python stress harness의 latency sample 보관을 bounded sampling으로 바꿔 bench artifact 후보를 분리했다. | `python-sustained-memory-metric` |
|
|
|
|
- 관련 경로: `dart/`, `go/`, `kotlin/`, `python/`, `typescript/`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_performance.sh`, `agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_stress.sh`
|
|
- 선행 작업: 고성능 병렬 운용 기준선과 최적화
|
|
- 후속 작업: 릴리즈 준비 또는 사용처별 성능 요구가 생길 때 package/runtime 정책 정리
|
|
- 기준 표준: `agent-test/local/proto-socket-performance-baseline.md`
|
|
- 참고 결과:
|
|
- `agent-test/runs/20260603-062724-proto-socket-stress-full.md`는 5개 언어 TCP/WS full `roundtrip,payload` 측정에서 required SKIP 없이 `stability_violations=0`을 기록했다.
|
|
- Go는 full baseline에서 TCP concurrency 256 throughput 약 `60748.4 rps`, p99 약 `4.432ms`, WS concurrency 256 throughput 약 `62631.5 rps`, p99 약 `4.872ms`로 reference fast path 후보였다. 1MB payload도 TCP p99 약 `21.076ms`, WS p99 약 `35.880ms`로 주요 병목 후보가 아니었다.
|
|
- `agent-test/runs/20260602-232000-proto-socket-stress-full.md`는 Go TCP burst 100k throughput 약 `201132.8 rps`, parallel 1024 clients throughput 약 `214665.2 rps`, p99 약 `154.621ms`, sustained 30분 throughput 약 `16264.9 rps`, p99 약 `0.646ms`, stability violation 0을 기록했다. sustained memory peak는 30초 약 `57.1MB`, 5분 약 `143.4MB`, 30분 약 `794.1MB`로 증가했으며, 이후 `go-sustained-memory-metric`에서 bench latency sample 누적 artifact로 분리하고 bounded sampling으로 보정했다.
|
|
- `agent-test/runs/20260603-035342-proto-socket-stress-quick.md`는 Go slow-mix를 deferred로 기록했다. 사유는 public request API의 concurrent `SendRequestTyped` completion order가 goroutine scheduling에 의존해 same-connection slow/fast response-arrival order를 결정론적으로 검증하기 어렵다는 점이며, 성능 병목으로 단정하지 않는다. 후속 검증은 public API completion order가 아니라 sequential same-client row 또는 내부 observer/helper가 per-connection FIFO를 직접 관찰하는 별도 row를 기준으로 한다.
|
|
- `agent-test/runs/20260605-115943-proto-socket-performance-full.md`는 Go idle full guard에서 TCP/WS concurrency 256, 1MB payload, burst 100k, parallel 1024, sustained rows가 stability violation 0 PASS임을 기록했다. baseline comparison의 Go WARN은 WS roundtrip concurrency 16 p99 `0.247ms -> 0.375ms`, WS sustained 30분 p99 `0.445ms -> 0.588ms` 두 건으로, sub-ms p99의 상대 변화가 threshold를 넘은 감시 항목이다. throughput 하락은 threshold 미만이며 Go runtime 최적화 trigger로 보지 않는다.
|
|
- Python은 full baseline에서 TCP concurrency 256 throughput 약 `10396.7 rps`, p99 약 `26.480ms`, WS concurrency 256 throughput 약 `7790.6 rps`, p99 약 `29.769ms`로 안정적인 중간 reference 후보였다. 1MB payload는 TCP p99 약 `18.856ms`, WS p99 약 `47.424ms`였고 stability violation은 0이었다.
|
|
- `agent-test/runs/20260602-232000-proto-socket-stress-full.md`는 Python TCP parallel 128 clients p99 약 `93.378ms`, 512 clients p99 약 `501.368ms`, 1024 clients p99 약 `1288.999ms`로 고동시성 p99 증가를 기록했다. 같은 결과의 sustained memory peak는 30초 약 `133.8MB`, 5분 약 `181.1MB`, 30분 약 `614.5MB`로 증가해 구현 leak과 bench artifact를 분리해야 한다.
|
|
- `agent-test/runs/20260603-035342-proto-socket-stress-quick.md`는 Python slow-mix를 throughput 약 `378.5 rps`, p99 약 `210.836ms`, stability violation 0으로 PASS 기록했다.
|
|
- Python client 기본 경로는 `TcpClient`와 `WsClient`가 gateway 인자 없이 `Communicator.initialize`를 호출하는 단일 경로다. `gateway_type`/`payload_size_threshold`는 README와 connect API에 노출되지 않은 저수준 `Communicator` 검증 knob이며, stress harness도 gateway profile을 TypeScript-specific으로 분리한다.
|
|
- `agent-test/runs/20260605-115943-proto-socket-performance-full.md`는 Python TCP/WS concurrency 256, 1MB payload, slow-mix 기준, parallel 1024, sustained rows를 stability violation 0 PASS로 기록했다. Python regression WARN은 WS concurrency=1 p99 `0.258ms -> 0.495ms` 1건뿐이며 throughput 하락 또는 hard gate 위반이 아니므로 reference watchlist로 둔다.
|
|
- Kotlin은 TCP concurrency 256 throughput 약 `20960.7 rps`, p99 약 `21.173ms`, TCP 1MB payload throughput 약 `430.7 rps`, p99 약 `24.975ms`로 TCP 경로는 현 기준에서 큰 병목 후보가 아니었다.
|
|
- Kotlin WS는 concurrency 16/64/256에서 각각 p99 약 `47.578ms`, `43.345ms`, `44.877ms`로 40ms대 고정 지연 패턴이 반복되고, WS 1KB payload p99 약 `42.651ms`, WS 1MB payload p99 약 `133.842ms`를 기록했다.
|
|
- Kotlin large payload memory peak는 TCP 1MB 약 `500.3MB`, WS 1MB 약 `668.3MB`로 기록되어, WS 지연 개선 시 JVM allocation/GC 영향과 queue/backlog 잔여 상태를 함께 분리해야 한다.
|
|
- `agent-test/runs/20260603-035352-proto-socket-stress-quick.md`는 Kotlin TCP/WS slow-mix를 deferred로 기록했다. 현재 보강 방향은 제품 결함 단정이 아니라, 같은 client의 concurrent request completion order가 coroutine scheduling에 의존하는 검증 모델을 결정론적으로 보정하는 것이다.
|
|
- Dart는 WS small roundtrip은 양호했지만 TCP concurrency 16/64/256에서 각각 p99 약 `43.626ms`, `44.404ms`, `49.109ms`로 40ms대 고정 지연이 반복되었다. TCP burst 100k throughput은 약 `154.4 rps`, TCP sustained 30분은 throughput 약 `385.3 rps`, p99 약 `44.079ms`였고, TCP 1MB payload는 throughput 약 `9.6 rps`, p99 약 `892.819ms`로 large payload TCP 병목 후보가 뚜렷했다.
|
|
- Dart WS는 concurrency 256 throughput 약 `42912.0 rps`, p99 약 `7.920ms`, WS 1MB payload throughput 약 `63.1 rps`, p99 약 `111.490ms`로 TCP보다 양호해, Dart 우선순위는 WS보다 TCP path hardening에 둔다.
|
|
- Dart 코드 확인 결과 `dart/lib/src/inbound_gateway_io.dart`에는 long-running `IsolateInboundGateway`가 있으나, `../dart-app-core`의 `IsolateManager`/`IsolateBase`/`IsoMessege` 모듈을 가져온 형태는 아니며 현재 제품 `ProtobufClient`/`WsProtobufClient` 기본 수신 경로에는 연결되어 있지 않다. 현재 사용은 `dart/test/communicator_test.dart`의 수동 attach 테스트 중심이다.
|
|
- `cd dart && dart test test/communicator_test.dart -r expanded`는 isolate gateway 단위 동작을 PASS로 확인했지만, 이는 실제 TCP/WS transport 성능 병목 해소 근거가 아니다. `cd dart && dart analyze`는 오류 없이 통과했고 `heartbeat_mixin.dart`의 `@override` annotation info 1건만 남았다.
|
|
- TypeScript는 TCP/WS small roundtrip은 대체로 양호했지만 WS 1MB payload p99 약 `228.648ms`로 large payload WS 병목 후보가 확인되었다.
|
|
- `agent-test/runs/20260603-080241-proto-socket-stress-full.md`는 TypeScript gateway full 결과에서 legacy inline control row가 WS throughput 약 `16242.7 rps`, p99 약 `1.887ms`였고, 현재 `worker_threads` gateway row는 throughput 약 `2499.3 rps`, p99 약 `205.654ms`로 악화되어 TypeScript worker-hop hardening 필요 근거가 되었다. TCP gateway row도 p99 약 `193.306ms`로 legacy inline control row p99 약 `43.095ms`보다 크게 나빴다. 이 수치는 gateway 비활성화 결론이 아니라, TypeScript mandatory receive path에서 `worker_threads` per-frame offload를 제거하거나 재설계해야 하는 overhead 기준이다.
|
|
- `agent-test/runs/20260603-092819-proto-socket-performance-quick.md`는 현재 HEAD `4dbeecf`에서 성능 전용 quick 표준이 same-language, cross-language, TypeScript gateway 구성요소를 모두 PASS로 aggregate 기록했다.
|
|
- `agent-test/runs/20260603-095712-proto-socket-performance-quick.md`는 baseline 비교 경로가 `compared rows: 90`, `missing baseline rows: 0`, `warning rows: 0`으로 동작함을 확인했다.
|
|
- 즉시 처리:
|
|
- [fast-path-ref] Go/Python reference fast path 분류는 `agent-test/runs/20260603-062724-proto-socket-stress-full.md`의 concurrency 256 및 1MB payload rows와 `agent-test/runs/20260602-232000-proto-socket-stress-full.md`의 burst/parallel/sustained rows를 근거로 완료 처리했다. Go는 fast path 기준점, Python은 중간 reference 기준점이며 둘 다 최우선 런타임 최적화 대상이 아니라 기준점 보강 대상으로 유지한다.
|
|
- [hotspot-report] 병목 리포트 정리는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/01_hotspot_report/complete.log`의 PASS 완료 이벤트와 `Roadmap Completion` 근거로 완료 처리했다.
|
|
- [ts-gateway-single-path] TypeScript default receive gateway 단일 경로 정리는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/01_ts_gateway_single_path/complete.log`의 PASS 완료 이벤트와 TypeScript check/test 결과를 근거로 완료 처리했다.
|
|
- [ts-worker-hop-removal], [gateway-overhead] TypeScript gateway 성능 row 분리와 worker_threads/control overhead 정량화는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/02+01_ts_gateway_perf_rows/complete.log`의 PASS 완료 이벤트, `agent-test/runs/20260604-103828-proto-socket-stress-quick.md`, `agent-test/runs/20260604-102233-proto-socket-performance-quick.md`, `agent-test/runs/20260604-104812-proto-socket-full-matrix.md`를 근거로 완료 처리했다.
|
|
- 즉시 처리:
|
|
- [compare-rule] full baseline comparison 실행 완료. `03_idle_full_baseline`을 baseline(`agent-test/runs/20260605-025842-proto-socket-performance-full.md`)으로 지정하여 비교 결과를 생성함. 결과 파일 `agent-test/runs/20260605-115943-proto-socket-performance-full.md`에 compared rows: 336, warning rows: 10, regression_result: WARN 기록 완료. Kotlin TCP parallel>=128 deadlock deferred 상태(INCOMPLETE)는 동일하게 유지됨.
|
|
- [go-slow-mix-model], [go-reference-guard]는 기존 stress/performance record 재해석과 병목 리포트 보강으로 완료 처리했다. [go-sustained-memory-metric]은 `05+04_go_sustained_memory_metric` archive PASS와 bounded sampling 적용 근거로 완료 처리했다.
|
|
- 즉시 처리:
|
|
- [python-high-parallel-p99]는 `agent-test/runs/20260602-232000-proto-socket-stress-full.md`의 Python TCP parallel 128/512/1024 PASS rows와 p99 증가 수치를 근거로 완료 처리했다.
|
|
- [python-gateway-api-policy]는 Python TCP/WS client API, README, stress harness gateway profile 분리를 확인해 기본 제품 경로를 gateway off 단일 경로로 정리하고 완료 처리했다.
|
|
- [python-reference-guard]는 `agent-test/runs/20260605-115943-proto-socket-performance-full.md`의 Python same-language/cross-language stability hard gate 0 PASS와 Python WARN 1건 watchlist 분리를 근거로 완료 처리했다.
|
|
- [python-sustained-memory-metric]은 `06_python_sustained_memory_metric` archive PASS와 Python sustained bounded sampling 적용 근거로 완료 처리했다. `agent-test/runs/20260605-213522-proto-socket-performance-quick.md`에서 same-language, cross-language, TypeScript gateway quick performance가 PASS이며, Python unit은 43 passed다.
|
|
- 즉시 처리:
|
|
- [dart-tcp-1mb]는 `07_dart_tcp_1mb_payload` archive PASS와 `agent-test/runs/20260605-225539-proto-socket-stress-full.md`의 Dart TCP 1MB row(`63.2 rps`, p99 `117.646ms`, stability 0)로 완료 처리했다.
|
|
- [ts-ws-1mb]는 `08_ts_ws_1mb_payload` archive PASS와 `agent-test/runs/20260606-023554-proto-socket-stress-full.md`의 TypeScript WS 1MB row(`31.6 rps`, p99 `255.039ms`, memory `162.5MB`, stability 0), 잔여 병목 문서화 근거로 완료 처리했다.
|
|
- 즉시 처리:
|
|
- [dart-tcp-fixed-latency], [dart-tcp-burst-sustained], [dart-heartbeat-cost]는 `09_dart_tcp_latency_heartbeat` archive PASS와 Roadmap Completion 근거로 완료 처리했다. 주요 근거는 `agent-test/runs/20260606-031314-proto-socket-stress-quick.md`, `agent-test/runs/20260606-031336-proto-socket-performance-quick.md`, `cd dart && dart test test/socket_test.dart -r expanded`다.
|
|
- [dart-isolate-backpressure], [dart-isolate-error-ordering], [dart-isolate-cleanup]은 `10_dart_isolate_gateway_contract` archive PASS와 Roadmap Completion 근거로 완료 처리했다. 검증은 `dart test test/communicator_test.dart -r expanded`, `dart test`, web compile PASS다.
|
|
- [dart-isolate-real-path]는 `11+10_dart_isolate_transport_path` archive PASS와 Roadmap Completion 근거로 완료 처리했다. 실제 TCP/WS transport 수신 경로 연결, web fallback 유지, focused stress/performance PASS를 근거로 삼았다.
|
|
- [dart-isolate-large-payload-transfer]는 `12+10,11_dart_isolate_large_payload` archive PASS와 Roadmap Completion 근거로 완료 처리했다. `agent-test/runs/20260606-050440-proto-socket-stress-full.md`의 Dart TCP/WS 1MB payload rows stability 0 및 `agent-test/runs/20260606-050449-proto-socket-performance-quick.md` PASS를 근거로 삼았다.
|
|
- 즉시 처리:
|
|
- [kotlin-slow-mix-model]은 `kotlin/crosstest/stress.kt`의 current deferred model과 `agent-test/runs/20260603-035352-proto-socket-stress-quick.md`의 Kotlin TCP/WS slow-mix INCOMPLETE 결과를 근거로 완료 처리했다. public concurrent completion order는 FIFO 결함 판정 기준에서 제외하고, 후속 검증은 sequential same-client row 또는 내부 observer/helper row로 둔다.
|
|
- `13_kotlin_ws_diagnostics`는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/13_kotlin_ws_diagnostics/complete.log` PASS로 완료됐다. 최종 review fresh rerun은 `./gradlew cleanTest test --tests "com.tokilabs.proto_socket.TlsWsTest"`, `./gradlew cleanTest test`, `./gradlew compileCrosstestKotlin`, Kotlin WS focused stress를 모두 PASS로 확인했다. 이 subtask는 Roadmap Completion 섹션이 없어 기능 Task 체크 없이 14번 hardening의 선행 근거로만 사용했다.
|
|
- [kotlin-ws-delay]는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/14+13_kotlin_ws_transport_hardening/complete.log` PASS와 Roadmap Completion 근거로 완료 처리했다. 주요 근거는 `cd kotlin && ./gradlew test`, `agent-test/runs/20260606-121117-proto-socket-stress-quick.md`, `agent-test/runs/20260606-121129-proto-socket-performance-quick.md`다.
|
|
- [kotlin-large-payload-memory], [kotlin-tcp-reference-guard]는 `agent-task/archive/2026/06/m-performance-hotspot-optimization/15+14_kotlin_ws_reference_guard/complete.log` PASS와 Roadmap Completion 근거로 완료 처리했다. 주요 근거는 `agent-test/runs/20260606-184707-proto-socket-stress-full.md`, `agent-test/runs/20260606-192408-proto-socket-performance-quick.md`, `cd kotlin && ./gradlew test`다. 남은 Milestone 기능 Task는 [perf-regression], [compat-matrix]다.
|