R04 장기 통계 시간 초과 수리와 통합 성능 판정 (2026-09-12)
- 기간: 2026-09-11~12, Codex 작업1개와 HQ 조율. 오너: “바벨릭 #1543 진행해줘. 나한테 물어보지 말고 끝까지 완주하고”.
- 랜딩: PR #1579 ·
17ce78123bb5297dedf9fbc34f10ea8f62fcf86f→release/v0.18.0. 마이그레이션20260915003000~202609150530006개. Edge/Vercel/Production 배포 없음. - 설계서: R04 이슈·Phase 계획, 최종 판정표.
- 정본: D11 계산 결과 저장 계약, 기존 G04 예산과 앱
RELEASE_PERFORMANCE_BUDGETS(변경 없음). - 도구: 앱
scripts/performance/measure/**·probe/**; 당시 scratch 실행기와 실패/중간 자료는 R04 증거에 source SHA와 압축 파일로 보존. - 게이트: ci:precheck-local 후보
07714a27/ based63926b1, 452.377초. static·unit3627pass/0fail/127skip·빈 DB 재생·schema·pgTAP 122파일/2444 assert 통과·실제 DB5묶음/큰 이력 격리·CRUD·수렴 통과. 첫 pgTAP1단언 실패와 관련44단언 수리 통과를 별도 보존. 최종 증거. 각 Phase의 앱 check와 관련 DB·브라우저 결과는 아래에 구분. Full·staging·Production 검증은 이 작업에서 실행하지 않음. - 버그리포트: BUG-126, BUG-127, BUG-128. 앞서 전달한 정규화 관측 교착/취소 경계 수리는 BUG-124와 PR#1577의 별도 release 반영.
- 계약: 비공개 typed 결과의 job/lease/revision·불변성·검증/원자적 게시·정리, 기존 원본/사용자 공개 계약 유지.
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 1 | 선행8개 release 포함·후보/대조·fixture/예산 고정 | 완료 |
| Phase 2 | 저장/계산/게시 비용 분해·확인된 수리·1/4/10년 반복 | 완료 |
| Phase 3 | 전후 혼합/10명/2기기·실제 InBody·동시성/회복 | 완료 |
| Phase 4 | outbox·G04/U05 화면·비통계/자원 경계 | 완료 |
| Phase 5 | 합격/초과/미입증 판정·원시SHA/명령·R05 인계 | 완료 |
1. 배경
v0.18.0 구조 변경 후 누적 이력과 동시 저장에서 실제 원본 보존·처리 비용·사용자 화면을 확인했다. 고정 seed1284/endDate2026-09-06의1/4/10년, 기존 예산·기존 worker 제한을 결과를 본 뒤 바꾸지 않았다. 대조 D11 직전 b0fa93ec와 최종 제품 72891abf, 측정기 09aaa9a4의 경계를 분리했다.
2. 문제 제기
긴 이력의 계산·게시가 기존 시간 제한을 넘었다
초기4년 게시6초, 대조10년 계산60초가 실패했다. 큰 JSON의 반복 전달·검증/재구성, 과거 점수 참조 반복 탐색·정책 해시/순수 함수 반복 호출, 기존 행을 JSON으로 변환하는 재사용 판단 비용을 실제 진단으로 분리했다. 중간 후보의10년 후속 저장8개는 첫 계산이60초를 넘어 기존 재시도로만 수렴했다.
상세 조회와 측정기에도 확인 가능한 문제가 있었다
10년 상세 조회가20ms 상한을 넘었고, 세트 점수 기준을 찾는 전체 이력 탐색·정렬을 줄일 필요가 있었다. 브라우저 측정기는 오래된 repository import를 참조했고, 빈 catalog slug를 정상 종목 identity로 가정해 실제0건으로 끝나는 문제를 부모의 실제 건수 검사로 발견했다. 과거 DOM267의 실제 적재 건수는 확인하지 못했다.
3. 해결 방안
원칙
D1(2026-09-11): 승인된 R04 범위에서 확인된 비용을 수리하고 원본·독립 full 동치·기존 예산을 유지한다. D2(2026-09-12 HQ 조율): 과거267/상한294/현재실제120세션317을 유지하며 역사 seed 미확인을 제품 회귀나 과거0건으로 단정하지 않는다.
접근
계산 결과의 타입·job/lease를 보존한 비공개 저장, 현재 원본판/불변 결과에 묶인 검증 재사용, 참조 후보 검색과 순수 동일 입력의 중복 비용 제거를 채택했다. timeout/시도 수 증설·원본 FK 제거·사용자 원본 수정·제품 예산 상향·근거 없는 DOM 삭제는 기각했다. 새로운 cache/관측 플랫폼·정책 변경도 추가하지 않았다.
4. 적용한 내용
Phase 1~2 — 고정 조건과 통계 수리
6개 마이그레이션으로 JSON 입력 지역화, 긴 이력 계산 경로, 비공개 결과19표·불변성/정리, 점수 참조 부분 인덱스/조회, NULL-safe native 재사용, 동일 순수 추정 입력 공유를 반영했다. 사용자 공개 결과와 원본/세대/영수증 계약은 유지했다. high인33000은10년2609세션/31308세트/23표81673원본의 populated upgrade288ms·7probe 오류0·중단/재개·사실 보존을 확인했다. RPE8 fixture의 해당 인덱스는0행이라 조밀한 실측 인덱스 비용은 미측정이다.
Phase 3~4 — 실제 통합 경계
후보와대조 각각혼합/10명/2기기2회씩12실행, 실제parser·인증Storage/RPC로InBody500행2회, 실제120세션G04 2회·260세션U05 12회,Chromium outbox1/100/1000건을 측정했다. 계산 중새저장·임대교체·원본삭제·충돌/재전송 관련DB23검사는0fail/0skip이었다.
Phase 5 — 최종 판정
검증 당시 소스와 제품DB SHA·tree, 실행명령·workload 지문·분포·원본/공개/압축SHA를 연결했다. 기존 dashboard/경보의 observability view를 사용하고 새 운영 플랫폼을 배포하지 않았다. 두 자체 DB의 통계cron5개씩을 기록한 원래 값으로 복원했다.
작업 중 드러난 것
초기 측정기 인자/import/위생/날짜 준비 실패,0건 무효표본, 중간 후보timeout·기존재시도·원본판40001 흡수,DB 없는skip과 실제DB검사를 모두 구분한다. 단순CLI exit0은 실제 fixture/정확성 검사를 대신하지 않는다. 일부 자원 시계열은 실행 중간부터이며 다른 담당자와 공유한 호스트의 차이를 특정SQL 원인으로 단정하지 않았다. 사전 검증 누락: 첫 precheck에서 기존 pgTAP가 비공개 관측을 옛 JSON 배열에서 읽어1개 단언이 실패했다. 게시 후 같은 복합 제외 단언은 통과했고, 계산 직후에도 현재job/lease/owner의 typed행에서 같은 조건을 확인하도록 바꿨다. 첫실패·전체수집·관련묶음·후속precheck 결과를 분리 보존했으며 우회하지 않았다.
5. 적용 결과
| 항목 | 결과 |
|---|---|
| 1/4/10년 | 최종6회·9RPC54개p95와연차증가상한 통과; 후속27개 원본/공개보존·독립full차이0 |
| 10년 초기/후속 | 대조초기60초실패 → 최종compute43.012/42.250초,publish5.587/4.979초,소진48.873/47.463초; 중간후속첫8회실패 → 최종8회53.655~58.128초·재시도0 |
| 혼합 저장 p95 | 28.616/29.058초 → 18.046/18.551초, 40ms 미충족 |
| 10명 부하 | 저장81.041/81.772 → 68.205/67.062ms,종료후반영확인0.903/0.520 → 68.731/65.559초로 지연 증가.최종수렴과실패시도각2회 흡수 기록 |
| freshness | 트랜잭션 경계 변화로 기준선과 동등 비교 불가, 해당 항목 합격 미입증.847/1101ms 유지 |
| outbox1000건 | 읽기7.84→7.48배·미러1.85→1.49배·전체조회15→11,기존상한충족 |
| U05 동일조건 | 12회/120전환오류0,DOMmobile317→317/desktop1757→1757.홈/전환 개선·악화 모두 원시값 보존 |
| G04 DOM | 과거267·상한294·현재실제120세션317; 과거실제seed미확인으로동등비교/합격미입증 |
| 지원 InBody | 실제17477bytes/500행·값/보관파일/재전송ID보존2회,가져오기203/118ms.20MB/browser최대heap검증 아님 |
| 검사 | Phase5check3627pass/0fail/127skip(104.912초),관련DB/pgTAP·실제브라우저 별도 증거; ci:precheck-local 후보 07714a27 / base d63926b1, 452.377초. static·unit3627pass/0fail/127skip·빈 DB 재생·schema·pgTAP 122파일/2444 assert 통과·실제 DB5묶음/큰 이력 격리·CRUD·수렴 통과. 첫 pgTAP1단언 실패와 관련44단언 수리 통과를 별도 보존. 최종 증거 |
| 출시 | release/v0.18.0 반영. 전체G04 합격·Full CI·staging·Production 성공 아님 |
6. 이번 개선으로 향상된 것
긴 이력의 첫 계산·게시가 기존 제한 안에서 끝났다
최종 fixture의 계산/게시 실패와 미반영을 해소하고, 실제 원본/공개 결과 동치와 변경 없는 행의 재사용을 자동 증거로 남겼다. 정당한 과거 영향 suffix와 전체계산 비용은 남으며 부분 비용 절감을 지원 사용자 수나 전체 개선율로 환산하지 않는다.
통합 이후에도 남은 한계를 추적할 수 있다
R05는 후보/원시SHA·재현명령·성능 초과·비교미입증을 함께 소비한다. 복구된 과거 실패와 현재 실패·미처리, 초기소진과개별freshness를 분리했다.
남은 것
G04 전체 수락은 미입증이다. 혼합40ms 미충족,10명 반영 지연 증가,freshness/DOM 비교 한계와 최대파일browser·native·Production/CDN/HTTPS SW/Edge 미측정을 R05에 인계한다. R05 staging 리허설과 R06 오너대기/Production 종료 조건을 완화하지 않는다. 이슈는 Production 성공 전 열림을 유지한다.