Hyrum's Law

Engineering

Hyrum 의 법칙

API를 사용하는 사용자가 충분히 많아지면, API가 공식적으로 약속한 계약이 무엇인지는 더 이상 중요하지 않다.

시스템에서 관찰 가능한 모든 동작에는 결국 그것에 의존하는 누군가가 생긴다.

Hyrum 의 법칙은 문서화된 인터페이스와 세부 사항의 경계가 실제 사용환경에서는 점점 흐려지는 현상을 말합니다.

인터페이스 사양(Spec) 이나 API Contract 등 에서 무엇을 보장한다고 명시했는지 관계없이 이 인터페이스를 사용하는 시스템과 사람이 많아지면 우리가 공식적으로 지원한다고 약속하지 않았던 포맷이나 동작에 의존하게 된다고 합니다.

다시 말해서

사용자가 많아지면 관찰할 수 있는 모든 특성이 누군가에겐 의존 대상이 될 수 있다.

라고 표현할 수 있습니다.

API 뿐만 아니라 라이브러리나 플랫폼과 같은 시스템에서도 마찬가지입니다. 사용자가 많아질수록 하위 호환성(Backward Compatibility) 을 신중하게 고려해야 합니다.

Hyrum Wright

이 용어는 Hyrum 의 동료인 Titus Winters 가 Software Engineering at Google (2020) 에서 처음 명명하였습니다.

Hyrum 은 구글 핵심 라이브러리에 적용한 변경 사항 중 원래라면 외부에서 전혀 알아차릴 수 없어야 하는 변경조차도 어딘가의 프로젝트를 망가뜨리는 경우가 많다는 사실을 발견했습니다.

예시: Google Abseil

대표적인 예시로 구글에서 오픈소스로 공개한 cpp 라이브러리 중 Abseil 이 있습니다.

해시맵을 순회하는 순서(iteration order)는 일반적으로 보장되지 않습니다. 하지만 실제 구현에서는 같은 입력에 대해 같은 순서가 반복해서 나타나는 경우가 많습니다.

그러다 보면 개발자는 보장되지 않는 동작임에도 불구하고 실제로 관찰되는 순서에 의존하는 코드를 작성할 수 있습니다.

처음에는 아무런 문제가 없어 보입니다.

하지만 라이브러리 개발자가 해시 함수나 내부 테이블 구조를 개선하면서 구현을 변경하면 순회 순서가 달라질 수 있습니다. 그 결과 기존의 테스트나 코드가 한꺼번에 깨질 수 있습니다.

이처럼 구현을 변경할 때마다 기존 사용자의 코드가 깨진다면 라이브러리 개발자는 결국 구현 세부 사항을 자유롭게 변경하기 어려워집니다. (Hyrum’s Law 가 만드는 비용)

이러한 문제 때문에 구글은 hash randomization 을 사용합니다. 순회 순서가 특정 구현에 의해 우연히 고정되어 있다는 가정 자체를 없애서 사용자가 순회 순서에 의존하는 것을 방지하는 것입니다.

마치며

라이브러리를 제공하는 입장에서는 버전이 올라갔다는 이유만으로 하위 호환성을 무시해서는 안 됩니다.

공식적으로 보장하지 않았던 동작이라 하더라도 많은 사용자가 의존하고 있다면 실제로는 변경의 여파가 상당히 커질 수 있습니다.

따라서 변경이 필요한 경우 deprecated, sunset 등의 방법으로 지원 종료를 미리 알리고 기존 사용자가 새로운 방식으로 이전할 수 있는 시간을 제공하는 것이 중요합니다.

하지만 원칙적으론 사용하는 사람의 책임이 크다고 생각합니다. 사용하는 측에서 외부 의존성에 대한 리스크를 충분히 이해하고 기술을 선택하고 코드를 작성해야합니다.