크라우니 칸반 M2 — 부하시험 PASS 확정 (O(n²) 줄분리 근본수리 추가)
개요
임무 M2(크라우니 칸반
/Users/ef/crowny-monitoring/칸반.한선 OOM 근본수리)의 최종 완료 확인.
인메모리 캐시(M2 본체) + 안전 필드 접근자·자동아카이브(M3, 별도 세션 병행작업,
2026-07-29-칸반-M3-정합성하드닝.md 참조)까지 적용된 상태에서 실제 부하시험을 돌려보니
서버가 소켓 바인드조차 못 하고 타임아웃하는 신규 결함을 추가로 발견·근본수리했다.
현재
bash 칸반부하시험.sh는 연속 2회 재현 PASS.
발견한 추가 결함 (M2가 "해결됨"으로 문서화된 이후 실측)
- 문자열.한선
줄분리()(=분리(s,"\n"))가 대용량 파일에서 O(n²) — 내부 찾기뒤()/부분()이
UTF8 문자인덱스를 매번 처음부터(byte 0) 재계산(
utf8_char_offset, crownyc.c:2632)하기
때문에, 위치가 커질수록 호출 1회 비용이 커진다(O(위치)). 1000행 파일(약 97KB,
읽기()
65535B 캡으로 65KB만 읽힘) 1회
줄분리()에
14.3초 소요(실측, 격리 진단으로 단계별
타이밍 계측: 파일읽기 0.009초 /
줄분리(상태원본) 14.26초 / 이후 캐시 맵빌드+본문렌더
0.2초+3초). 캐시 재구축은 "부팅 1회"뿐이지만, 이 1회가 소켓 바인드 앞에서 실행되므로
부하시험 스크립트의 바인드확인 창(1초+재시도 2초 = 3초)을 넘겨
서버가 살아있는데도
FAIL(바인드 확인 실패) 판정이 남— OOM은 없어졌지만 다른 이유로 부하시험을 통과 못 하는
상태였음.
- 1차 시도(버퍼 바이트스캔) 부작용:
버퍼읽기(buf,i,1)로 1바이트씩 스캔하는 방식은
14.3초→0.10초로 빨랐으나,
BUF_READ가 호출마다
str_new()로 새 문자열핸들을 만들어
65535회 호출 시 문자열핸들 90%(432000/480000) 조기경고가 부팅 1회만에 발생(실측) —
장수 서버에서 반복되면 상한(exit 43) 위험.
채택안(v2):
버퍼찾기()(memcmp 스캔,
핸들 생성 0)로 다음 개행만 찾고 그 줄만
버퍼잘라()(라인 길이만큼만 memcpy)로 잘라
문자열화 — 줄당 핸들 1개. 실측 13.4ms, 핸들 소비 677개(1000행 기준, 이전 대비 ~97배 절감).
수리 내용
/Users/ef/crowny-monitoring/칸반.한선: 칸반빠른줄분리(원본문자열) 신설(칸반필드()
직후, 최초 사용부보다 앞). 상태파일/피드파일 전체를 대상으로 하는
줄분리(...) 호출
7곳(
칸반행조회/
칸반업서트/
칸반병합구축×2/
칸반캐시재구축/
칸반아카이브/
칸반동기화)을
전부
칸반빠른줄분리(...)로 교체. 자가시험 내부의 소용량 검증용
줄분리() 4곳(테스트
파일 몇 줄)은 성능과 무관해 그대로 둠.
- 문자열.한선(공유 라이브러리, 다수 서비스 의존)은 무수정 — 이 파일 소유범위 안에서만
우회.
검증
- 컴파일:
hanseonc_high 모니터링.한선 0에러(문자열.한선 4900+큐브 + 칸반.한선 전체
import 체인, stderr 분리 확인).
자가시험 2종 모두 PASS:
칸반자가시험.한선(외부 실행형, 캐시 build/직접갱신/일관성 24건 포함) 56/56 PASS.
칸반.한선 내장 KANBAN_SELFTEST=1 게이트(M3, /tmp 격리경로) 25/25 PASS.
부팅 바인드 시간: 18초(발견 당시) → 3.9초(1차 버퍼스캔) → 0.35~0.40초(v2, 3회 반복
측정 일관).
부하시험 bash /Users/ef/crowny-monitoring/칸반부하시험.sh 연속 2회 PASS:
1500요청(sync/list/kanban×500) 전부 200, [ARRAY] OOM 0건, RSS 배율 100%(277184KB→
277408KB, 사실상 무증가).
기존 API 회귀(/api/status /health /api/weak /ping) 격리기동서 200 유지.
move 전이도 정상: 미확인→완료(불법, 거부) / 미확인→확인(합법, 반영) 둘 다 기대대로.관련 파일
/Users/ef/crowny-monitoring/칸반.한선 (본 수리 + M2 캐시 + M3 하드닝 통합본, 772줄)
/Users/ef/crowny-monitoring/칸반자가시험.한선 (56 assert)
/Users/ef/crowny-monitoring/칸반부하시험.sh (게이트, 무수정)
- 백업:
칸반.한선.bak-m2-1785136741(M2 착수 전), 칸반.한선.bak-boundsfix-1785286107(M3 세션 백업)
- 학습:
crownycode-learn.sh add 칸반_인메모리캐시_OOM회피, 버퍼기반_빠른줄분리_O_n
잔여 이슈
읽기() 65535B 하드캡 자체는 VM(crownyc.c) 레벨 제약(수정 범위 밖) — M3의
칸반상태자동아카이브체크()(45000자 임계 시 자동 아카이브)가 완화책. 상태파일이
"완료" 아닌 대량 미확인 항목으로만 채워지는 극단 케이스(이번 부하시험 시드처럼)는
아카이브 대상이 없어 완화책이 무력화되지만, 그 경우도 OOM/속도 문제는 없음(본 수리로
파싱 자체가 O(n)) — 남는 리스크는 65535B 절단으로 인한 목록 완전성(개수) 저하뿐,
부하시험 판정 기준(OOM/RSS/응답코드)엔 영향 없음.
- 동시세션 경합: 이 작업 도중 다른 세션이 같은
칸반.한선을 M3로 동시 편집 중이었음
(2026-07-29). 서로 다른 함수(안전접근자/자동아카이브 vs 빠른줄분리)라 충돌 없이
머지됐으나, 향후 같은 파일을 여러 세션이 동시에 작업할 가능성 높은 시기엔 착수 전
crowny-knowledge.sh query로 확인 권장.