부록 G - 러스트가 만들어지는 과정과 ‘Nightly 러스트’

이 부록은 러스트가 어떻게 만들어지는지와 이것이 러스트 개발자로서의 여러분에게 어떤 영향을 미치는지에 대해 설명합니다.

정체되지 않는 안정성

언어로서 러스트는 코드의 안정성을 매우 중요하게 생각합니다. 러스트가 여러분이 무언가 구축할 수 있는 견고한 토대가 되기를 바라지만, 무언가 계속 바뀐다면 이는 불가능할 것입니다. 동시에 새로운 기능을 실험할 수 없다면, 더 이상 변경할 수 없는 릴리즈 이후에야 중요한 결함을 발견할 수도 있습니다.

이 문제에 대한 우리의 해결책은 ‘정체되지 않는 안정성 (Stability Without Stagnation)’이라 부르는 것으로, 기본 원칙은 다음과 같습니다: 여러분이 안정적인 새 버전의 stable 러스트로 업그레이드하는 것을 두려워할 필요가 없어야 한다는 것입니다. 각 업그레이드는 고통 없이 진행되어야 하지만, 그러면서도 새로운 기능이 추가되고 버그가 줄어들며 컴파일 시간이 단축되어야 합니다.

칙칙폭폭! 릴리즈 채널과 기차 타기

러스트 개발은 기차 스케줄에 따라 운영됩니다. 즉, 모든 개발은 러스트 저장소의 master 브랜치에서 이루어집니다. 릴리즈는 Cisco IOS 및 기타 소프트웨어 프로젝트에서 사용되어 온 소프트웨어 릴리즈 기차 모델 (train model) 을 따릅니다. 러스트에는 세 가지 릴리즈 채널이 있습니다:

  • Nightly
  • Beta
  • Stable

대부분의 러스트 개발자는 주로 stable 채널을 사용하지만, 실험적인 새 기능을 시도하고 싶은 사람들은 nightly나 beta를 사용할 수 있습니다.

다음은 개발 및 릴리즈 프로세스가 어떻게 작동하는지에 대한 예시입니다: 러스트 팀에서 러스트 1.5 릴리즈를 작업 중이라고 가정해 봅시다. 이 릴리즈는 2015년 12월에 이루어졌지만, 실제 버전 번호와 함께 제공될 것입니다. 새로운 기능이 러스트에 추가됩니다: 즉 새 커밋이 master 브랜치에 저장됩니다. 매일 밤, 새로운 nightly 버전의 러스트가 생성됩니다. 날마다 릴리즈되며, 이러한 릴리즈는 릴리즈 인프라에 의해 자동으로 생성됩니다. 따라서 시간이 지남에 따라 릴리즈는 밤마다 한 번씩 다음과 같이 보입니다:

nightly: * - - * - - *

6주마다 새 릴리즈를 준비할 시간이 됩니다! 러스트 저장소의 beta 브랜치는 nightly에서 사용하는 master 브랜치에서 분기됩니다. 이제 두 개의 릴리즈가 있습니다:

nightly: * - - * - - *
                     |
beta:                *

대부분의 러스트 사용자는 beta 릴리즈를 적극적으로 사용하지는 않지만, 자신들의 CI 시스템에서 beta를 테스트하여 러스트가 가능한 문제점을 발견하는 데 도움을 줍니다. 한편, 매일 밤 여전히 nightly 릴리즈가 있습니다:

nightly: * - - * - - * - - * - - *
                     |
beta:                *

문제점이 하나 발견되었다 칩시다. 문제점이 stable 릴리즈에 들어가기 전에 beta 릴리즈에서 테스트할 시간이 있어서 다행입니다! master에 수정이 적용되어 nightly가 수정되고, 그런 다음 수정이 beta 브랜치로 역으로 포팅되어 새로운 beta 릴리즈가 생성됩니다:

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

첫 번째 beta가 생성된 후 6주가 지나면, stable 릴리즈가 출시됩니다! stable 브랜치는 beta 브랜치에서 생성됩니다:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

만세! 러스트 1.5가 완료되었습니다! 그러나 한 가지를 잊어버렸습니다: 6주가 지났으므로 러스트 1.6의 새로운 beta도 필요합니다. 따라서 stablebeta에서 분기한 후, beta의 다음 버전은 다시 nightly에서 분기됩니다:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

이것이 ‘기차 모델’이라고 불리는 이유는 6주마다 릴리즈가 ‘역에서 출발’하지만, stable 릴리즈로 도착하기 전에 beta 채널을 통해 여행을 계속해야 하기 때문입니다.

Rust는 시계처럼 6주마다 릴리즈됩니다. 한 번의 Rust 릴리즈 날짜를 알면 다음 릴리즈 날짜도 알 수 있습니다: 6주 후입니다. 6주마다 릴리즈가 예정되어 있다는 것은 다음 기차가 곧 온다는 의미입니다. 어떤 기능이 특정 릴리즈에 빠지는 일이 생겼어도 걱정할 필요가 없습니다: 곧 다른 릴리즈가 출시될 예정이니까요! 이렇게 하면 릴리즈 마감일에 임박해서 미완성된 기능을 몰래 넣어야 하는 부담을 줄일 수 있습니다.

이 프로세스 덕분에 여러분은 언제든지 러스트의 다음 빌드를 확인하고 업그레이드가 쉬운지 직접 확인할 수 있습니다: beta 릴리즈가 예상대로 작동하지 않는 경우 팀에 보고하여 다음 stable 릴리즈가 나오기 전에 수정할 수 있습니다! beta 릴리즈에서 버그가 발생하는 경우는 비교적 드물지만, rustc는 여전히 소프트웨어일 뿐이며 버그가 존재할 수 있습니다.

불안정한 기능

이 릴리즈 모델에는 한 가지 더 볼 것이 있습니다: 바로 불안정한 기능입니다. 러스트는 ‘기능 플래그’라는 기법을 사용하여 특정 릴리즈에서 어떤 기능이 활성화되는지 결정합니다. 새로운 기능이 활발하게 개발 중인 경우 master에 들어가고, 따라서 따라서 nightly 릴리즈에 적용되지만 기능 플래그 에 숨겨져 있습니다. 여러분이 사용자로서 개발 중인 기능을 사용해 보고 싶은 경우, 러스트의 nightly 릴리즈를 사용 중이어야 하며 해당 기능을 채택하기 위해 적절한 플래그를 소스 코드에 어노테이션해야 합니다.

러스트의 beta 또는 stable 릴리즈를 사용하는 경우에는 기능 플래그를 사용할 수 없습니다. 이것이 새로운 기능을 영원히 안정적으로 선언하기 전에 실제로 사용해 볼 수 있도록 하는 열쇠입니다. 최신 기능을 사용하고 싶은 사람은 그렇게 할 수 있고, 견고한 경험을 원하는 사람은 stable 버전을 유지하면서 코드가 깨지지 않을 것이라는 확신을 가질 수 있습니다. 정체되지 않는 안정성이지요.

이 책에는 안정적인 기능에 대한 정보만 담고 있으며, 진행 중인 기능들은 계속 바뀌고 있으므로, 이 책이 작성된 시점과 이 기능들이 stable 빌드에서 활성화되는 시점이 확실히 다를 것입니다. nightly 전용 기능에 대한 설명서는 온라인 문서에서 찾을 수 있습니다.

Rustup과 러스트 Nightly의 역할

Rustup은 러스트의 다른 릴리즈 채널 간 변경을 전역 또는 프로젝트별로 쉽게 할 수 있도록 도와줍니다. 기본적으로는 stable 러스트가 설치되어 있습니다. 예를 들어 nightly를 설치하려면 다음과 같이 입력하면 됩니다:

$ rustup toolchain install nightly

rustup을 사용하면 설치된 모든 툴체인 (toolchain, 러스트 릴리즈 및 연관된 컴포넌트) 을 모두 볼 수 있습니다. 아래는 저자 중 한 명의 Windows 컴퓨터의 예시입니다:

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

보시다시피 stable 툴체인이 기본값입니다. 대부분의 러스트 사용자는 대부분의 경우 stable 버전을 사용합니다. 대부분의 경우 stable 버전을 사용하고 싶지만, 최신 기능을 고려하고 있어서 특정 프로젝트에서는 nightly 버전을 사용할 수도 있습니다. 그렇게 하려면 해당 프로젝트의 디렉터리에서 rustup override를 사용하여 해당 디렉터리에 있을 때는 rustup이 사용해야 하는 것이 nightly 툴체인임을 설정하면 됩니다:

$ cd ~/projects/needs-nightly
$ rustup override set nightly

이제 ~/projects/needs-nightly 내에서 rustc 또는 cargo를 호출할 때마다 rustup은 기본값인 stable 러스트가 아닌 nightly 러스트를 사용하고 있음을 확실히 해줄 것입니다. 이 기능은 러스트 프로젝트가 많을 때 유용합니다!

RFC 과정과 팀

그렇다면 이러한 새로운 기능에 대해 어떻게 알 수 있을까요? 러스트의 개발 모델은 RFC (Request For Comments, 의견 요청) 프로세스를 따릅니다. 러스트에 어떤 개선점을 제안하고 싶은 경우, RFC라는 제안서를 작성할 수 있습니다.

누구나 러스트를 개선하기 위해 RFC를 작성할 수 있으며, 제안은 여러 주제별 하위 팀으로 구성된 러스트 팀에 의해 검토 및 논의됩니다. 러스트 웹사이트에 팀의 전체 목록이 있으며, 프로젝트의 각 영역에 대한 팀들이 포함되어 있습니다: 언어 디자인, 컴파일러 구현, 인프라, 문서화 등이 있지요. 적합한 팀이 제안서와 의견을 읽고, 자신의 의견을 작성하고, 최종적으로 합의를 통해 기능을 수락하거나 거부합니다.

기능이 수락되면, 러스트 저장소에 이슈가 열리고, 누군가가 이를 구현할 수 있습니다. 이 기능을 아주 잘 구현하는 사람은 처음에 기능을 제안한 사람이 아닐 수도 있습니다! 구현이 준비되면 ‘불안정한 기능’절에서 설명한 대로 기능 게이트 뒤편에 숨겨져 master 브랜치에 저장됩니다.

시간이 지나 nightly 릴리즈를 사용하는 러스트 개발자가 새 기능을 사용해 볼 수 있게 되면, 팀원들은 해당 기능에 대해, 그리고 이 기능이 nightly 릴리즈에서 어떻게 작동했는지 논의하고, stable 러스트에 포함할지 여부를 결정합니다. 앞으로 나아가기로 결정되면 기능 게이트가 제거되고 해당 기능은 이제 안정적인 것으로 간주됩니다! 새로운 stable 러스트 릴리즈로 가는 열차를 타게 됩니다.