Skip to content

flaky: 부하 상황에서 실제-프로세스 테스트(worker init/handshake)가 타임아웃에 근접해 간헐 실패 #3

Description

@devswha

요약

CPU/IO 경합이 심한 환경(로디드 CI 러너, 컨테이너 동시 실행 등)에서 npm test를 돌리면, 실제 자식 프로세스를 spawn하는 무거운 테스트들이 자체 타임아웃에 근접하면서 간헐적으로 timeout 실패할 수 있음. 기능 결함이 아니라 테스트 타임아웃이 부하에 취약한 문제.

관찰 증거 (Docker에서 동시 3중 부하로 재현)

동일 테스트의 여유 시 vs 부하 시 소요 시간:

테스트 여유 시 부하 시
native core carries the real worker initialize and shutdown protocol ~240ms 3332–3404ms
production worker executable performs a protocol-only handshake and shutdown ~1050ms 3209–3440ms
fails closed on malformed JSON, methods, invalid JSON values, and direct byte bounds ~700ms 1530–1919ms
  • 동일 부하로 6회 반복 중 1회, server 스위트에서 watcher가 아닌 테스트 1건이 timeout으로 실패(재현률 낮음, 부하 의존).

영향 범위

  • server/gjc-core-host.test.ts — native/worker 실제 프로세스를 spawn하는 케이스.
  • server/gjc-worker.test.ts — 동일한 for (let attempt = 0; attempt < 500; ...) = 5초 폴링 패턴 존재.

원인

inotify 이벤트 / child 프로세스 응답이 I/O 바운드라 CPU/IO 경합 시 프레임·응답 관찰이 지연됨. 테스트 타임아웃이 여유 시 기준으로 타이트하게 잡혀 있어 부하 환경(특히 GitHub 2코어 공유 러너)에서 간헐적 red를 유발할 수 있음.

참고: 이미 반영된 관련 수정

native core recursively watches multiple roots and filters non-transcript files의 watcher-frame 폴링 타임아웃을 5s→20s, 프로세스 가드를 10s→30s로 상향해 동일 부하에서도 안정화 확인함(워킹트리 변경, 아직 미커밋). 본 이슈는 나머지 무거운 테스트들에 대한 동일 하드닝을 추적하기 위한 것.

제안

  • worker/handshake 계열 테스트의 내부 타임아웃을 관찰 최악치의 충분한 배수(예: 현행의 4–6배)로 상향.
  • 또는 scripts/run-tests.mjs에서 부하 민감 파일을 직렬 실행하거나 --test-concurrency를 낮춰 파일 병렬도를 제한.
  • server/gjc-worker.test.tsattempt < 500(5s) 폴링 루프도 함께 상향.

재현 방법

동일 이미지(Node + Rust)로 npm test를 3개 이상 동시 실행해 CPU/IO 경합을 만들면 위 테스트들의 소요 시간이 3s+로 늘어나는 것을 관찰할 수 있음.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions