NDC 참관기: 변화량 추적을 중심으로 한 저비용 고효율의 지속적인 코드퀄리티 관리법

6/1일자 오후 세션이었던 네오플의 송창규 님의 강연입니다.

이하는 간략한 요약.

게임 업계의 패러다임 변화: 새 게임 만들기 => ‘성공한 게임’의 개선, 유지

그런 이유로 지속 가능성이 중요하다

코드 퀄리티 관리

깨진 창문 효과: 관리되지 않는다는 느낌을 주면 안된다.

하지만, 라이브 서비스의 경우, 그 규모에 압도 되서 (코드 베이스가) 슬럼화될 수 있다. 청소 메타포: 매일 매일 청소할 게 생기고, 하지 않는다고 못 버티는건 아니지만, 계속 해서 불편해짐..

코드 퀄리티 관리와 비슷하다. 그러나 프로젝트가 시간이 흘러 코드 베이스는 계속 해서 (무한정) 커지지만, 거기에 투입할 수 있는 프로그래머 수에는 한계가 있다는 점은 큰 차이

난관

  • (코드 베이스가 커서) 깨진 창문을 찾지도 못한다
  • 이에 들어가는 비용
  • 개선해도 잘 안보이고, 개선 사항이 유지되기도 힘들다
  • (라이브 서비스) 코드는 계속해서 오염된다

=> 학습된 무기력을 낳는다

어떻게 할까?

자동화 + 시간에 따른 변화에 중점

(정적 분석에서는) 코드를 데이터로 보고 이를 분석한다. 여기에 시간 개념을 포함해서 소스 코드를 시간에 따라 `변화하는 데이터’로 보자.

어떻게 나눌까?

논리적 분류, 의존성에 따른 분류, 그리고 변동성에 따른 분류.  프로젝트 유지 비용을 낮게 하려면 변동성이 높은 것과 낮은 것을 잘 나눠야 한다.

단, 변동성의 개념에 따라, 낮은 변동성인 요소가 높은 변동성인 요소에 의존하면 높은 변동성인 요소가 되어버린다.

변동성의 측정

‘;정량적으로 측정?’ => ‘소스 저장소의 변화량을 측정’ 기대 효과: 많이 바뀐 곳이 (아마) 중요한 곳일 것이다

변동성이 높은 곳(파일)을 개선하면?

  • 신규 프로그래머의 진입 장벽이 낮아지고, 정보 과잉을 해소할 수 있다
  • 개선 효율이 높다
  • 변동성이 낮은 파일들을 묶어서 별도 프로젝트/dll로 분리할 수 있다.[^1]

문제:  만약 파급력이 높고, 변동성도 높은 파일이 있다면? 명백히 좋지 않으니 어떻게 하지 않으면.

이런 파일을 어떻게 찾을까? 변동성, 파급력, 시간에 따른 파급력이 모두 높은 파일?

Python 스크립트로 소스 저장소 데이터를 측정해서,

  • 변동성이 높으면서 파급력도 높은 파일 : 시간에 따른 파급력 조사, 재컴파일된 파일 수 조사
  • 파일이 아니라 함수 수준에서 찾아보자
  • 로그 메시지의 특정 단어 Bug, fix, … 등에서 힌트를 추가
  • 함수 라인 별 변화량 추적 (LCS 쓰기; FAIL)

(이 부분에서는 던파, 크아 BnB, 메이플 스토리(일부는 누락) 소스 저장소 데이터를 모아서 보여줬다. 개략적으로 자주 변하는 파일과, 그 부분에 대한 간략간략한 개선 방향을 언급함)

숫자의 함정에 유의하자:

  • 이걸 기준으로 프로그래머의 능력을 평가하면 곤란 (커밋 당 버그 수 등등을 측정하면 망함; 인센티브 룰을 최대한 치팅하게 됨)
  • 릴리즈 전 빠른 커밋 과 빠른 버그 발견 및 수정은 오히려 권장되어야 함

지속 가능한 코드 퀄리티 관리 방법들

  • 영역을 구분하고 점진적으로 하자.
  • 직관의 함정: 추가되는 코드도 더럽혀 진다.
  • 다시 어지럽히지 말아야 한다

잘 안된다 -> 공정 개선이 필요

공정 개선 팁

Assertion: 특히 MT환경에서 효과가 좋았다.

  • Lock ordering 검사
  • needs-lock 매크로
  • Caller-thread check

등등.

Assertion을 나누는 것,

  • Domain에 따라 나누고 (perf-critical/non-critical)
  • 컴파일 시간에 할지를 나누고
  • 허용되는 액션에 따라 나누고 (ignore, msg-box, log, send-packet)
  • MsgBox 에 따라 나누고

Validator는 지속 가능성이 낮다: 강제하기 힘듬

지속가능하게 하려면?

  • 빌드 시스템을 이용하거나
  • commit hook을 이용해서 강제하거나
  • (새로 작성하거나 변경할 때는) 이를 검사하지만, 이전 코드 등에서는 이를 무시하게 할 수 있어야

매우 재밌게 들었다.

연사가 충분한 케이스 스터디 ‘넥슨 내 장기간 지속된 프로젝트에서 추출한 데이터로 ‘쓸 만 하겠다’라는 생각을 충분히 줬다. 이 아이디어를 당장 팀 내 저장소에 넣고 돌려봐도 쓸모 있을 듯 함.

이런 류의 세션에서는 역시 “실제로 해보고”, “케이스 스터디도 있고” 란 점이 주는 신뢰도에 많은 영향을 준다.

Validator 같은 부분도 @ipkn 이 말하던 ‘스크립트 변수 edit-distance로 잘못 쓴거 찾자’랑 비슷한 느낌이기도 하더라.

첫 날 메이플 스토리 개발 스토리 세션에서도 말한 내용이지만, “기존 레거시 코드"에 대해서 예외를 인정하고, (특히나 변경되지 않는 부분이라면 더더욱) 새로 추가하거나 변경하는 부분에 중점을 두는 것은 “실제로 적용하기 위해선 꼭 필요한 정책"이라고 생각한다.

단순히 “새로 할 때 잘 하자"가 아니라, 라이브 서비스나 이미 충분히 진행 중인 서비스에서 적용할 수 있게, “저비용 고효율 방법론"을 제시한 점이 아주 좋았음.

[^1] 빌드 시간 개선;  봐야할 장소 줄이기 등등; 연사가 측정한 바로는 변동성 적은 것만 묶어서 unity build하면 효과가 좋다고 한다(던파 클라 빌드시간 3x분 -> 1x분.