부록 G - 러스트가 만들어지는 방식과 “Nightly Rust”
이 부록은 러스트가 어떻게 만들어지며, 그 과정이 러스트 개발자인 여러분에게 어떤 영향을 주는지에 관한 내용입니다.
정체 없는 안정성
러스트는 언어로서 여러분 코드의 안정성을 매우 중요하게 생각합니다. 러스트가 튼튼한 기반이 되기를 바라며, 모든 것이 계속 바뀐다면 그런 기반이 될 수 없습니다. 동시에, 새 기능을 실험할 수 없다면 중요한 결함을 릴리스 뒤에야 발견하게 될 수 있고, 그때는 이미 바꿀 수 없을지도 모릅니다.
이 문제에 대한 러스트의 해법이 바로 “정체 없는 안정성(stability without stagnation)” 입니다. 그리고 우리의 기본 원칙은 다음과 같습니다. 안정 버전의 새 러스트로 업그레이드하는 일을 절대로 두려워할 필요가 없어야 한다. 각 업그레이드는 고통 없이 이루어져야 하며, 동시에 새 기능, 더 적은 버그, 더 빠른 컴파일 시간을 가져와야 한다.
칙칙폭폭! 릴리스 채널과 기차 타기
러스트 개발은 기차 시간표 에 맞춰 이루어집니다. 즉, 모든 개발은 러스트 저장소의 메인 브랜치에서 이뤄집니다. 릴리스는 Cisco IOS 와 다른 소프트웨어 프로젝트에서도 사용된 소프트웨어 릴리스 트레인 모델을 따릅니다. 러스트에는 세 가지 릴리스 채널 이 있습니다.
- Nightly
- Beta
- Stable
대부분의 러스트 개발자는 주로 안정 채널을 사용하지만, 실험적인 새 기능을 써 보고 싶은 사람은 nightly 나 beta 를 사용할 수 있습니다.
개발과 릴리스 과정이 어떻게 돌아가는지 예를 들어 봅시다. 러스트 팀이 Rust 1.5 릴리스를 작업 중이라고 가정합시다. Rust 1.5 는 2015년 12월에 나왔지만, 여기서는 현실적인 버전 번호를 제공하는 예시로 쓰겠습니다. 러스트에 새 기능 하나가 추가됩니다. 새 커밋이 메인 브랜치에 들어갑니다. 매일 밤 새로운 nightly 러스트 버전이 만들어집니다. 매일이 릴리스 날이고, 이 릴리스들은 릴리스 인프라가 자동으로 만듭니다. 시간이 지나면 릴리스는 밤마다 대략 이렇게 보입니다.
nightly: * - - * - - *
6주가 지나면 새 릴리스를 준비할 때가 됩니다! 러스트 저장소의 beta 브랜치는 nightly
가 사용하는 메인 브랜치에서 갈라집니다. 이제 릴리스는 두 개가 됩니다.
nightly: * - - * - - *
|
beta: *
대부분의 러스트 사용자는 beta 릴리스를 적극적으로 쓰지는 않지만, CI 시스템에서 beta 를 대상으로 테스트해 러스트가 회귀 버그를 미리 발견하도록 돕습니다. 그 사이에도 nightly 릴리스는 매일 밤 계속 나옵니다.
nightly: * - - * - - * - - * - - *
|
beta: *
회귀 버그가 하나 발견되었다고 합시다. 다행히 그 버그가 안정 릴리스에 숨어들기 전에
beta 를 시험해 볼 시간이 있었습니다! 수정은 메인 브랜치에 먼저 적용되어 nightly 가
고쳐지고, 그다음 beta 브랜치로 백포트되어 새 beta 릴리스가 만들어집니다.
nightly: * - - * - - * - - * - - * - - *
|
beta: * - - - - - - - - *
첫 beta 가 만들어지고 6주가 지나면 안정 릴리스 시점입니다! stable 브랜치는
beta 브랜치에서 만들어집니다.
nightly: * - - * - - * - - * - - * - - * - * - *
|
beta: * - - - - - - - - *
|
stable: *
좋습니다! Rust 1.5 가 완성되었습니다! 하지만 잊은 것이 하나 있습니다. 6주가 지났으니
이제 다음 버전인 Rust 1.6의 새 beta 도 필요합니다. 따라서 stable 이 beta
에서 갈라져 나온 뒤, 다음 버전의 beta 는 다시 nightly 에서 갈라집니다.
nightly: * - - * - - * - - * - - * - - * - * - *
| |
beta: * - - - - - - - - * *
|
stable: *
이것을 “기차 모델”이라고 부르는 이유는, 6주마다 릴리스 하나가 “역을 떠나지만”, 안정 릴리스로 도착하기 전에는 반드시 beta 채널을 거쳐 가야 하기 때문입니다.
러스트는 시계처럼 정확하게 6주마다 릴리스됩니다. 러스트 릴리스 하나의 날짜를 알고 있다면 다음 릴리스 날짜도 알 수 있습니다. 정확히 6주 뒤입니다. 6주마다 릴리스가 예약되어 있다는 점의 좋은 점은 다음 기차가 곧 온다는 것입니다. 어떤 기능이 특정 릴리스를 놓치더라도 걱정할 필요가 없습니다. 곧 다음 릴리스가 오기 때문입니다. 덕분에 릴리스 직전 미완성 상태의 기능을 억지로 밀어 넣으려는 압박도 줄어듭니다.
이 과정 덕분에 언제나 러스트의 다음 빌드를 써 보고 업그레이드가 쉬운지 직접 확인할
수 있습니다. beta 릴리스가 기대한 대로 동작하지 않으면 팀에 보고해, 다음 안정 릴리스
전에 고치게 할 수 있습니다! beta 릴리스에서 깨지는 일은 비교적 드물지만, rustc
도 결국 소프트웨어이므로 버그는 존재합니다.
유지보수 기간
러스트 프로젝트는 가장 최신의 안정 버전만 지원합니다. 새 안정 버전이 릴리스되면, 이전 버전은 수명 종료(EOL)에 도달합니다. 즉, 각 버전은 6주 동안 지원됩니다.
불안정 기능
이 릴리스 모델에는 한 가지 요소가 더 있습니다. 바로 불안정 기능입니다. 러스트는 주어진 릴리스에서 어떤 기능이 활성화되는지 결정하기 위해 “기능 플래그(feature flag)” 라는 기법을 사용합니다. 새 기능이 활발히 개발 중이라면 메인 브랜치, 즉 nightly 에 들어가지만 기능 플래그 뒤에 가려집니다. 여러분이 사용자로서 작업 중인 기능을 직접 시험해 보고 싶다면 그렇게 할 수는 있습니다. 다만 nightly 러스트를 사용해야 하고, 소스 코드에 적절한 플래그를 달아 명시적으로 opt-in 해야 합니다.
beta 나 stable 러스트를 사용하는 경우에는 어떤 기능 플래그도 사용할 수 없습니다. 이 점이 새 기능을 영구적으로 안정화하기 전에 실전 환경에서 써 볼 수 있게 해 줍니다. 최신 실험 기능을 쓰고 싶은 사람은 그렇게 할 수 있고, 단단한 경험을 원하는 사람은 stable 에 머물면서 코드가 깨지지 않음을 알 수 있습니다. 이것이 바로 정체 없는 안정성입니다.
이 책에는 안정 기능에 대한 정보만 담겨 있습니다. 진행 중인 기능은 계속 변하고 있고, 책이 쓰인 시점과 그 기능이 안정 빌드에 들어가는 시점 사이에서도 분명 달라질 것이기 때문입니다. nightly 전용 기능 문서는 온라인에서 찾을 수 있습니다.
Rustup 과 Rust Nightly 의 역할
Rustup 은 전역 단위든 프로젝트 단위든, 러스트의 서로 다른 릴리스 채널 사이를 쉽게 바꿀 수 있게 해 줍니다. 기본적으로는 stable 러스트가 설치됩니다. 예를 들어 nightly 를 설치하려면 다음과 같이 합니다.
$ rustup toolchain install nightly
설치한 모든 툴체인 (러스트 릴리스와 관련 구성요소들)도 rustup 으로 확인할 수
있습니다. 다음은 이 책 저자 중 한 명의 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 절차와 팀
그렇다면 이런 새 기능에 대해 어떻게 알게 될까요? 러스트의 개발 모델은 Request For Comments (RFC) 절차 를 따릅니다. 러스트를 개선하고 싶다면 RFC 라는 제안 문서를 작성할 수 있습니다.
누구나 러스트 개선을 위한 RFC 를 쓸 수 있고, 이 제안은 여러 주제별 하위 팀으로 구성된 러스트 팀에 의해 검토되고 논의됩니다. 모든 팀 목록은 러스트 웹사이트 에서 볼 수 있습니다. 언어 설계, 컴파일러 구현, 인프라, 문서 등 프로젝트 각 분야의 팀이 포함되어 있습니다. 적절한 팀이 제안과 댓글을 읽고, 자기들의 의견도 남긴 뒤, 결국 그 기능을 받아들일지 거부할지에 대한 합의가 형성됩니다.
기능이 받아들여지면 러스트 저장소에 이슈가 열리고, 누군가 그 기능을 구현할 수 있습니다. 아주 잘 구현한 사람이 처음 제안한 사람과 동일하지 않을 수도 있습니다! 구현이 준비되면, “불안정 기능” 절에서 설명한 것처럼 기능 게이트 뒤에 둔 상태로 메인 브랜치에 들어갑니다.
시간이 지나 nightly 릴리스를 사용하는 러스트 개발자들이 새 기능을 충분히 시험해 보면, 팀 구성원들은 그 기능과 nightly 에서의 동작 결과를 논의하고, stable 러스트에 넣을지 말지를 결정합니다. 앞으로 진행하기로 결정되면 기능 게이트가 제거되고, 그 기능은 이제 안정적이라고 간주됩니다! 그리고 기차를 타고 다음 안정 러스트 릴리스로 들어갑니다.