2P by neo 5일전 | favorite | 댓글 1개
  • Hyrum의 법칙과 Golang

    • 최근 Gocodebase를 탐색하던 중 흥미로운 주석을 발견함
    • "Hyrum의 법칙 때문에 이 텍스트는 변경할 수 없음"이라는 주석이 있는 코드 예시
    • MaxBytesError 구조체의 Error() 메서드에서 "http: request body too large"라는 오류 메시지를 반환함
  • Hyrum의 법칙

    • Hyrum Wright라는 Google 소프트웨어 엔지니어의 이름을 딴 원칙
    • 많은 사용자가 API를 사용할 경우, 시스템의 모든 관찰 가능한 동작은 누군가에 의해 의존될 것이라는 내용
    • 코드에서 의도적이든 우연이든 관찰 가능한 모든 동작은 결국 누군가에 의해 의존됨
    • 오류 메시지를 변경하면 기존 코드가 깨질 수 있는 이유 설명
  • Golang에서의 사례

    • crypto/rsainternal/weak 패키지에서도 Hyrum의 법칙을 언급하는 주석 발견
    • crypto/rsa/rsa.gocrypto/rsa/pss.go에서의 주석 예시
    • internal/weak 패키지에서의 주석 예시
  • 관찰

    • Golang에만 국한된 것이 아님
    • JavaScript의 진화 과정에서도 유사한 현상 관찰 가능
    • 이러한 현상을 Hyrum의 법칙이라고 부름
  • 최종 생각

    • 다른 사람들이 의존할 수 있는 코드를 변경할 때 주의해야 한다는 점을 상기시킴
    • 의도치 않은 동작이 의존되지 않도록 시스템을 설계하는 것이 중요함
    • 작은 변화가 큰 영향을 미칠 수 있다는 점을 기억해야 함
Hacker News 의견
  • Hyrum's Law는 유용한 관찰이지만, 잘못된 결론을 내리지 않도록 주의해야 함. 함수의 전체 실행 시간도 관찰 가능한 속성이므로, 함수를 최적화하여 더 빠르게 만드는 것이 99.99999999%의 사용자에게는 좋을 수 있지만, 이는 깨지는 변경이 될 수 있음. 따라서 "깨지는 변경"은 기술적 계약이 아닌 사회적 계약임을 이해해야 함. 라이브러리 작성자는 API의 변경되지 않을 부분을 문서화하고, 사용자에게 공감해야 함. 라이브러리 소비자는 문서화되지 않은 인터페이스를 사용하는 것이 위험할 수 있음을 이해하고, 작성자에게 공감해야 함

  • Go 언어에서는 Hyrum's Law와 하위 호환성을 매우 중요하게 생각함. 예를 들어, GenerateKey 함수에서 MaybeReadByte를 사용하여 알고리즘이 고정되지 않도록 함. ECDSA 키의 문제를 해결하기 위해 노력 중임. 맵의 반복 순서는 무작위로 설정되어 내부를 노출하지 않도록 함. rand.Rand의 출력은 호환성 약속의 일부로 간주되어 개선을 위해 많은 노력을 기울임. 문서에서 어떤 약속을 할지, 어떤 행동을 부인할지에 대해 항상 논의함

  • 특정 문제에 대한 해결책으로 문자열 기반 오류 대신 센티넬 오류를 사용할 것을 권장함. API 소비자가 비기술적 문자열에 의존하지 않도록 사전 정의된 오류 값, 타입 또는 상수를 사용해야 함. Hyrum's Law는 존재하지만 그 영향을 완화할 수 있음

  • Hyrum's Law에 대항하는 방법으로 랜덤성을 추가하는 것이 있음. QUIC 프로토콜은 사용하지 않는 필드를 무작위 값으로 설정하여 라우터가 패킷을 식별하는 데 의존하지 않도록 함. 이를 "greasing"이라고 하여 "ossification"을 방지함

  • Golang 설계자는 예외를 원하지 않았지만, 비형식적 오류는 문제가 있음. 패턴 매칭 없이 형식화된 오류를 처리하는 방법에 대한 논의가 필요함

  • 한 직장에서 오류 메시지의 오타를 발견하고 수정했으나, 그 오타에 의존하는 종속성이 너무 깊어 수정이 불가능하여 원래 상태로 되돌려야 했던 경험이 있음

  • Go의 오류는 열거형 타입으로 변경할 수 있었지만, 문자열을 타입으로 사용하여 소비자가 어떻게 의존할지 알 수 없음. 이는 더 나은 대안이 존재하는데도 불구하고 오래된 설계 결정임

  • Hyrum's Law는 Robustness Principle/Postel's Law와 정반대임. 수용하는 것에 대해 자유로우면, 그 방법을 이해하고 문서화해야 함. API가 수용하는 것에 대해 자유롭지 않도록 설계하려고 함

  • Hyrum's Law는 테스트에서 자주 나타남. 보장되지 않은 동작에 대한 가정으로 인해 다양한 유형의 테스트가 깨짐. 예를 들어, Hashmap의 요소 순서 변경, 오류 메시지 변경, 윤일 처리 방식 변경 등이 있음

  • 일부 패키지 작성자는 Hyrum's Law를 더 수용할 수 있음. json 패키지의 주석에서 내부 세부 사항이지만 널리 사용되는 패키지가 이를 링크네임을 통해 접근하는 것을 발견함