NetworkModuleTest는 ServerEngine을 중심으로 구성된 분산 서버 테스트베드입니다. 현재 기본 런타임 흐름은 TestClient → TestServer → TestDBServer(옵션)이며, DB 연동은 프로토타입(로그/플레이스홀더 중심) 단계입니다.
- ServerEngine: INetworkEngine/BaseNetworkEngine, AsyncIOProvider, Session/SessionManager, 공용 유틸, DB 모듈(ODBC/OLEDB)
- TestServer: NetworkEngine 기반 테스트 서버, 패킷 수신/처리, DBTaskQueue(비동기 작업)
- TestDBServer: NetworkEngine 기반 DB 서버 프로토타입, Ping/Pong 및 PingTime 기록 (DB 저장은 플레이스홀더)
- TestClient: SessionConnect + Ping/Pong + RTT 통계
| 모듈 | 상태 | 비고 |
|---|---|---|
| ServerEngine | 진행 중 | Windows x64 Release 1000 클라이언트 PASS / Linux Docker epoll+io_uring PASS |
| TestServer | 프로토타입 | 세션/핑 처리, DB 옵션(ENABLE_DATABASE_SUPPORT) |
| TestDBServer | 프로토타입 | Ping/Pong 및 PingTime 기록, DB 저장은 플레이스홀더 |
| TestClient | 프로토타입 | RTT 통계, 자동화 테스트 모드(maxPings) 포함 |
- A. KeyedDispatcher:
BaseNetworkEngine::mLogicThreadPool→KeyedDispatcher mLogicDispatcher교체.Session::mRecvMutex제거 (key-affinity 직렬화 보장) - B. TimerQueue:
Concurrency/TimerQueue.h/.cpp신규. DB ping 스레드 루프 →ScheduleRepeat교체. WorkerLoopmRunning=false시 즉시 break 버그 수정 포함 - C. AsyncScope:
Session::mAsyncScope추가.Close()시Cancel()호출 → recv 작업 억제. 풀 재사용 버그 수정:Session::Reset()에서mAsyncScope.Reset()호출 추가 (mCancelled=true잔존 문제 해결) - D. Send 백프레셔:
Session::Send()→SendResult반환 (Ok/QueueFull/NotConnected).SEND_QUEUE_BACKPRESSURE_THRESHOLD=64 - E. NetworkEventBus:
Network/Core/NetworkEventBus.h/.cpp신규 싱글턴. 다중 구독자 이벤트 수신 지원
Dockerfile(Ubuntu 22.04, gcc-12, liburing-dev, libsqlite3-dev)docker-compose.yml— 3 서비스: dbserver(9001) → server(9000) → client_epoll / client_iouringCMakeLists.txt— ServerEngine(정적) + TestServer + DBServer + TestClientscripts/run_integration.sh,scripts/entrypoint_client.sh(TCP 탐침 → TestClient 실행)run_docker_test.ps1— Windows 런처 (-Backend epoll|iouring|both,-NoBuild,-Single)- 테스트 결과: epoll PASS (Session 5) / io_uring PASS (Session 20), RTT 0~1ms (kernel 6.6.87.2-WSL2)
- 상세 로그:
Docs/Performance/Logs/20260302_191739_linux/
- 증상: io_uring 클라이언트만
SessionConnectRes수신 실패 (EAGAIN, error 11) - 원인:
Session::Close()→mAsyncScope.Cancel()설정 후Session::Reset()에서mCancelled초기화 누락 → 풀 재사용 시 모든 로직 태스크 silently skip - 수정:
AsyncScope::Reset()메서드 추가 +Session::Reset()에서 호출 - TestClient 수정: 자동화 테스트 모드(
--pings N)에서 퐁을 하나도 못 받으면 exit code 1 반환 (meta PASS/FAIL 정확도 향상)
- 1000/1000 PASS, Errors=0, Server WS=143.6 MB (이전 193.7 MB → 약 50 MB 감소)
- RTT: avg=2ms, max=20ms @1000 clients
- Dead code 제거:
Platforms/AsyncBufferPool.h/.cpp,Platforms/Windows/RIOBufferPool.h,Platforms/Linux/IOUringBufferPool.h,Interfaces/IBufferPool.h삭제 - 신규 모듈:
Core/Memory/— 플랫폼 독립 버퍼 풀 인터페이스 + 구현 3종IBufferPool.h—BufferSlot{ptr, index, capacity}공용 인터페이스 (namespace Core::Memory)StandardBufferPool.h/.cpp—_aligned_malloc/posix_memalign기반, IOCP·epoll·kqueue 공용RIOBufferPool.h/.cpp— VirtualAlloc + 1×RIORegisterBuffer,GetSlabId()/SlotPtr()헬퍼IOUringBufferPool.h/.cpp—posix_memalign+io_uring_register_buffers,#if __linux__전용
- RIOAsyncIOProvider 리팩토링: inline slab 멤버 제거 →
Core::Memory::RIOBufferPool mRecvPool, mSendPool으로 교체 (락 순서:mMutex→ 풀 내부 lock, deadlock 없음)
ServerEngine/Tests/Protocols/PingPong.*테스트 프로토콜에 검증 필드(랜덤 숫자/문자 에코) 추가ParsePong()에서 원본 대조로 검증 가능 (GetLastValidationResult())- 기본 운영 경로(
PacketDefine.h기반 TestClient/TestServer 패킷)와는 분리된 테스트 전용 포맷
- 1000/1000 PASS, Errors=0, Server WS=143.6 MB (이전 193.7 MB → 약 50 MB 감소)
- RTT: avg=2ms, max=20ms @1000 clients
AsyncBufferPool::Acquire/ReleaseO(n) 선형 탐색 → O(1) 프리리스트 (vector<size_t>스택 +unordered_map인덱스)Session::ProcessRawRecv()N 패킷 = Nvector<char>힙 할당 → 배치 평탄 버퍼(1 alloc) + 단일 패킷 패스트패스(0 alloc)Session::Send()IOCP 경로 per-sendvector<char>alloc 제거 →SendBufferPool싱글턴 O(1) 슬롯 할당Session::PostSend()IOCP 경로 두 번째 memcpy 제거 → 풀 슬롯 포인터 직접 wsaBuf 설정 (zero-copy WSASend)- 신규 파일:
Network/Core/SendBufferPool.h/.cpp
RIOAsyncIOProviderper-I/ORIORegisterBuffer→ 사전 등록 slab pool 2개 (recv/send)NetworkTypes.h::MAX_CONNECTIONS10000 → 1000 (Non-Paged Pool 한계 대응)- CQ 깊이 공식
effectiveMax * 2 + 64으로 동적 계산 - 결과: 1000 클라이언트 PASS (WSA 10055 해결)
ProcessRawRecvO(n) erase → O(1) 오프셋 기반 누적 버퍼 처리 (mRecvAccumOffset)mPingSequenceuint32_t→std::atomic<uint32_t>(핑 타이머-IO 스레드 경쟁 조건 해소)- 세션 생성 경로 정리:
SessionFactory제거 →SessionPool의Core::Session+SessionManager::SetSessionConfigurator()경로로 통일 DBTaskQueue내부 구조 개편: 단일 공유 큐에서 워커별 독립 큐 +sessionId % workerCount라우팅으로 전환. 현재TestServer설정값은Initialize(1, ...)유지CloseConnection이벤트 경로:mLogicDispatcher기반 직렬 처리로 정리DBPingTimeManager→ServerLatencyManager통합PlatformDetect.h:PLATFORM_WINDOWS/LINUX/MACOS+DB_BACKEND_ODBC/OLEDB컴파일 타임 매크로 추가