Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ภาคผนวก G - กระบวนการสร้างภาษา Rust และ “Nightly Rust”

ภาคผนวกนี้เกี่ยวกับวิธีการสร้างและพัฒนาภาษา Rust และการที่กระบวนการดังกล่าวส่งผลต่อคุณในฐานะนักพัฒนา Rust อย่างไร

เสถียรภาพโดยไม่หยุดนิ่ง (Stability Without Stagnation)

ในฐานะภาษาโปรแกรม Rust ใส่ใจเกี่ยวกับเสถียรภาพ (stability) ของโค้ดของคุณเป็นอย่าง มาก เราต้องการให้ Rust เป็นรากฐานที่มั่นคงดั่งหินผาที่คุณสามารถต่อยอดพัฒนาสิ่งต่างๆ ได้ และหากมีการเปลี่ยนแปลงเกิดขึ้นตลอดเวลา เรื่องดังกล่าวก็คงเป็นไปไม่ได้ ในขณะเดียวกัน หากเราไม่มีการทดลองกับคุณลักษณะ (features) ใหม่ๆ เลย เราก็อาจไม่พบข้อบกพร่องที่สำคัญจนกระทั่งมีการเผยแพร่ฟีเจอร์เหล่านั้นออกไปแล้ว ซึ่งถึงตอนนั้นเราก็ไม่สามารถกลับไปแก้ไขเปลี่ยนรูปแบบการทำงานได้อีก

แนวทางแก้ไขปัญหานี้ของเราคือสิ่งที่เราเรียกว่า “เสถียรภาพโดยไม่หยุดนิ่ง (stability without stagnation)” และหลักการชี้นำของเราคือ: คุณไม่ควรต้องหวาดกลัวกับการอัปเกรด Rust เป็นเวอร์ชันเสถียร (stable) เวอร์ชันใหม่ การอัปเกรดแต่ละครั้งควรปราศจากความยุ่งยาก แต่ในขณะเดียวกันก็ควรนำพาคุณลักษณะใหม่ๆ มาให้คุณ มีจุดบกพร่องที่น้อยลง และช่วยให้ประมวลผลคอมไพล์ได้เร็วขึ้น

ปู๊นๆ! ช่องทางการเผยแพร่และขบวนรถไฟซอฟต์แวร์ (Release Channels and Riding the Trains)

การพัฒนาภาษา Rust ทำงานตามระบบ ตารางเดินรถไฟ นั่นคือการพัฒนาทั้งหมดจะทำบนสาขาหลัก (main) ในคลังเก็บโค้ด (repository) ของ Rust การเผยแพร่รุ่นใหม่ๆ จะดำเนินตามรูปแบบขบวนรถไฟซอฟต์แวร์ (release train model) ซึ่งเป็นระบบที่เคยนำไปใช้ในโครงการพัฒนา Cisco IOS และซอฟต์แวร์อื่นๆ มาแล้ว โดยช่องทางการเผยแพร่ (release channels) สำหรับ Rust จะมีอยู่ 3 ช่องทางหลัก ได้แก่:

  • Nightly
  • Beta
  • Stable

นักพัฒนา Rust ส่วนใหญ่จะเลือกใช้ช่องทาง stable เป็นหลัก แต่สำหรับผู้ที่ต้องการทดลองใช้คุณลักษณะใหม่ๆ ที่อยู่ในขั้นทดลอง ก็สามารถสลับไปใช้งาน nightly หรือ beta ได้

นี่คือตัวอย่างการทำงานของกระบวนการพัฒนาและการเผยแพร่: สมมติว่าทีมงาน Rust กำลังจัดทำ Rust เวอร์ชัน 1.5 (เวอร์ชันนี้ออกเผยแพร่จริงเมื่อเดือนธันวาคม ปี 2015 แต่เรานำมาเป็นข้อมูลเพื่อแสดงเลขเวอร์ชันประกอบให้เห็นภาพชัดเจน) เมื่อมีฟีเจอร์ใหม่เพิ่มเข้ามาใน Rust: คอมมิตใหม่จะถูกบันทึกส่งไปยังสาขาหลัก (main) ทุกๆ คืน คอมไพเลอร์ Rust เวอร์ชัน nightly จะถูกสร้างขึ้น ทุกๆ วันจึงเปรียบเหมือนวันเผยแพร่ และรุ่นย่อยเหล่านี้จะถูกสร้างโดยโครงสร้างพื้นฐานการเผยแพร่ของเราโดยอัตโนมัติ ดังนั้น เมื่อเวลาผ่านไป รุ่นที่เผยแพร่ของเราจะมีลักษณะดังนี้ในทุกๆ คืน:

nightly: * - - * - - *

ทุกๆ 6 สัปดาห์ จะถึงเวลาเตรียมเผยแพร่รุ่นใหม่! สาขา beta ในคลังเก็บโค้ดของ Rust จะแตกแขนงแยกออกจากสาขาหลัก (main) ที่ nightly ใช้งานอยู่ ตอนนี้เราจะมีระบบเผยแพร่อยู่ 2 ส่วน:

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

ผู้ใช้ Rust ส่วนใหญ่จะไม่ได้ใช้งานรุ่นทดสอบ beta ในระหว่างทำงานทั่วไป แต่จะระบุให้ทำการทดสอบโปรแกรมเทียบกับเวอร์ชัน beta ในระบบการรวมโค้ดต่อเนื่อง (CI system) ของตนเอง เพื่อช่วยโครงการ Rust ตรวจหาข้อบกพร่องที่อาจเกิดความถดถอยในการทำงาน (regressions) ในขณะเดียวกัน ทุกๆ คืนก็ยังคงมีการปล่อยรุ่น nightly ออกมาอย่างต่อเนื่อง:

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

สมมติว่ามีข้อบกพร่องของการถดถอยถูกตรวจพบ ถือเป็นเรื่องดีที่เรามีเวลาทดสอบเวอร์ชัน beta ก่อนที่ข้อบกพร่องนั้นจะหลุดรอดไปถึงรุ่นเสถียร (stable release)! วิธีแก้ไขจะถูกบันทึกส่งเข้าไปยังสาขาหลักเพื่อแก้ไขปัญหาใน nightly จากนั้นการแก้ไขนี้จะถูกพอร์ตย้อนกลับ (backported) มายังสาขา beta และจะสร้างรุ่น beta รุ่นอัปเดตใหม่ออกมา:

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

หลังจากสร้าง beta แรกเป็นเวลา 6 สัปดาห์ ก็ได้เวลาเผยแพร่รุ่นเสถียร! สาขา stable จะถูกสร้างขึ้นมาจากสาขา beta:

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

ไชโย! Rust 1.5 เสร็จสมบูรณ์แล้ว! อย่างไรก็ดี เราลืมไปอย่างหนึ่ง: เนื่องจากเวลาล่วงเลยไปแล้ว 6 สัปดาห์ เราจึงต้องมีรุ่น beta ใหม่ของ Rust เวอร์ชัน ถัดไป นั่นคือเวอร์ชัน 1.6 ด้วยเช่นกัน ดังนั้น หลังจากสาขา stable แตกออกจาก beta แล้ว สาขา beta เวอร์ชันถัดไปก็จะแตกแยกออกมาจาก nightly อีกครั้ง:

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

วิธีนี้เรียกว่า “รูปแบบขบวนรถไฟ (train model)” เนื่องจากในทุกๆ 6 สัปดาห์ จะมีรุ่นปล่อยใหม่ออกจาก “สถานีรถไฟ” แต่ยังต้องเดินทางผ่านช่องทาง beta เพื่อทดสอบตรวจสอบระบบก่อนที่จะเทียบชานชาลากลายเป็นรุ่นเสถียร (stable release)

การออกเวอร์ชันใหม่ของ Rust จะเกิดขึนทุกๆ 6 สัปดาห์ตรงเวลาดั่งเครื่องจักรกล หากคุณทราบวันที่การเผยแพร่รุ่นใดรุ่นหนึ่งของ Rust คุณย่อมรู้ว่ารุ่นถัดไปจะออกเมื่อใด นั่นคือ 6 สัปดาห์ถัดไปนั่นเอง ข้อดีของการมีรอบการเผยแพร่ทุกๆ 6 สัปดาห์คือ รถไฟขบวนถัดไปจะมาถึงในไม่ช้า หากมีฟีเจอร์ใดพลาดการเผยแพร่ในรอบนี้ ก็ไม่จำเป็นต้องกังวล: ขบวนถัดไปจะมาถึงในอีกไม่นาน! วิธีนี้ช่วยลดความกดดันที่จะต้องเร่งรีบใส่ฟีเจอร์ที่อาจยังไม่เสร็จสมบูรณ์ร้อยเปอร์เซ็นต์เข้าสู่ช่วงเวลาก่อนเส้นตายการเผยแพร่

ด้วยกระบวนการนี้ คุณจึงสามารถทดสอบตรวจสอบ build ถัดไปของ Rust ได้อยู่เสมอ เพื่อยืนยันด้วยตนเองว่ากระบวนการอัปเกรดเป็นเรื่องง่าย: หากรุ่น beta ทำงานได้ไม่เป็นไปตามที่คาดหวัง คุณสามารถรายงานปัญหาให้ทีมพัฒนาทราบเพื่อแก้ไขปัญหาให้เรียบร้อยก่อนที่รุ่นเสถียรจริงจะออกเผยแพร่! ความเสียหายในรุ่น beta ถือว่าเกิดขึ้นค่อนข้างน้อย แต่ rustc ก็ยังคงเป็นซอฟต์แวร์ชิ้นหนึ่ง ข้อผิดพลาด (bugs) จึงย่อมมีโอกาสเกิดขึ้นได้เป็นธรรมดา

ระยะเวลาการดูแลรักษาความเสถียร (Maintenance time)

โครงการ Rust จะให้การสนับสนุนดูแลเฉพาะเวอร์ชันเสถียรเวอร์ชันล่าสุดเท่านั้น เมื่อมีการออกเวอร์ชันเสถียรเวอร์ชันใหม่ เวอร์ชันเก่าจะถึงจุดสิ้นสุดการสนับสนุน (end of life - EOL) ทันที ซึ่งหมายความว่าในแต่ละเวอร์ชันจะมีระยะเวลาได้รับการสนับสนุนดูแลเป็นเวลา 6 สัปดาห์

คุณลักษณะที่ยังไม่เสถียร (Unstable Features)

ยังมีเงื่อนไขเพิ่มเติมอีกอย่างหนึ่งสำหรับโมเดลการเผยแพร่นี้: คุณลักษณะที่ยังไม่เสถียร (unstable features) ภาษา Rust ใช้เทคนิคที่เรียกว่า “แฟล็กคุณลักษณะ (feature flags)” เพื่อระบุว่าฟีเจอร์ใดที่จะเปิดใช้ในรุ่นที่เผยแพร่นั้นๆ หากคุณลักษณะใหม่กำลังอยู่ระหว่างการพัฒนา โค้ดจะถูกบันทึกส่งไปยังสาขาหลัก และส่งผลให้ปรากฏใน nightly แต่จะถูกปิดซ่อนไว้ภายใต้ แฟล็กคุณลักษณะ หากคุณในฐานะผู้ใช้ต้องการทดลองใช้งานฟีเจอร์ที่ยังพัฒนาไม่เสร็จสิ้นนี้ คุณสามารถทำได้ แต่จำเป็นต้องใช้งานคอมไพเลอร์ Rust รุ่น nightly และเพิ่มคำกำกับ (annotate) ลงในโค้ดต้นฉบับของคุณด้วยแฟล็กที่เหมาะสมเพื่อตกลงยอมรับการทดลองใช้งาน

หากคุณใช้งาน Rust รุ่น beta หรือ stable คุณจะไม่สามารถเปิดใช้งานแฟล็กคุณลักษณะใดๆ ได้ นี่คือกุญแจสำคัญที่ช่วยให้พวกเราสามารถเก็บข้อมูลการใช้งานจริงของฟีเจอร์ใหม่ๆ ได้ ก่อนที่จะประกาศรับรองความเสถียรของฟีเจอร์เหล่านั้นตลอดไป ผู้ที่ชื่นชอบทดลองสิ่งใหม่ๆ ในระดับขอบเทคโนโลยี (bleeding edge) ก็สามารถทำได้ ส่วนผู้ที่ต้องการใช้งานระบบที่เสถียรอย่างสมบูรณ์แบบก็สามารถยึดมั่นกับรุ่น stable และมั่นใจได้ว่าโค้ดของพวกเขาจะไม่พังเสียหาย เสถียรภาพโดยไม่หยุดนิ่ง

หนังสือเล่มนี้มีเฉพาะข้อมูลเกี่ยวกับคุณลักษณะที่เสถียรแล้วเท่านั้น เนื่องจากคุณลักษณะที่อยู่ระหว่างการพัฒนายังคงมีการเปลี่ยนแปลงอยู่เสมอ และย่อมมีความแตกต่างกันระหว่างช่วงเวลาที่เขียนหนังสือเล่มนี้กับช่วงเวลาที่ฟีเจอร์เหล่านั้นได้รับการเปิดใช้งานใน build เวอร์ชันเสถียร คุณสามารถศึกษาเอกสารอธิบายฟีเจอร์เฉพาะ nightly เพิ่มเติมได้ทางออนไลน์

Rustup และบทบาทของ Rust Nightly

เครื่องมือ Rustup ช่วยอำนวยความสะดวกให้การสลับเปลี่ยนไปมาระหว่างช่องทางการเผยแพร่ต่างๆ ของ Rust เป็นเรื่องง่าย ทั้งในแบบครอบคลุมทั้งระบบ (global) หรือแยกเฉพาะในแต่ละโครงการ โดยค่าเริ่มต้น คุณจะมี Rust รุ่น stable ติดตั้งอยู่แล้ว ตัวอย่างการติดตั้ง nightly เช่น:

$ rustup toolchain install nightly

คุณยังสามารถตรวจสอบ ชุดเครื่องมือ (toolchains) (เวอร์ชันปล่อยของ Rust และส่วนประกอบที่เกี่ยวข้อง) ทั้งหมดที่คุณติดตั้งผ่าน 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 ถูกกำหนดเป็นค่าเริ่มต้น ผู้ใช้ Rust ส่วนใหญ่จะใช้ stable เกือบทั้งหมด อย่างไรก็ดี คุณอาจต้องการใช้ stable เป็นหลัก แต่เลือกใช้ nightly ในบางโครงการเป็นพิเศษเนื่องจากต้องการใช้งานฟีเจอร์ขั้นสูงบางอย่าง ในการดำเนินการดังกล่าว คุณสามารถรันคำสั่ง rustup override ภายในไดเรกทอรีโครงการนั้น เพื่อระบุให้ rustup เรียกใช้งานชุดเครื่องมือ nightly เสมอเมื่อคุณเข้ามาทำงานภายในไดเรกทอรีนี้:

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

ตอนนี้ ทุกๆ ครั้งที่คุณพิมพ์เรียกใช้งาน rustc หรือ cargo ภายในโฟลเดอร์ ~/projects/needs-nightly ตัว rustup จะคอยควบคุมดูแลให้คุณใช้ Rust เวอร์ชัน nightly แทนการเรียกใช้เวอร์ชันเสถียรที่เป็นค่าเริ่มต้นตามปกติ สิ่งนี้จะมีประโยชน์อย่างมากเมื่อคุณต้องดูแลโครงการ Rust จำนวนหลายโครงการ!

กระบวนการ RFC และทีมงานพัฒนา (The RFC Process and Teams)

แล้วคุณจะเรียนรู้เกี่ยวกับคุณลักษณะใหม่ๆ เหล่านี้ได้อย่างไร? รูปแบบการพัฒนาของ Rust จะดำเนินตาม กระบวนการยื่นขอความคิดเห็น (Request For Comments - RFC process) หากคุณต้องการแนะนำให้มีการปรับปรุงสิ่งใดใน Rust คุณสามารถร่างเอกสารข้อเสนอขึ้นมา ซึ่งเรียกว่า RFC

ทุกคนสามารถเขียนเอกสาร RFC เพื่อแนะนำการปรับปรุงพัฒนาภาษา Rust ได้ โดยข้อเสนอจะได้รับการตรวจสอบและหารือร่วมกันโดยทีมงาน Rust ซึ่งประกอบไปด้วยทีมย่อยที่ดูแลในหัวข้อต่างๆ คุณสามารถดูรายการทีมทั้งหมดได้ที่ เว็บไซต์ทางการของ Rust ซึ่งมีทีมที่รับผิดชอบในแต่ละด้านของโครงการ เช่น ทีมออกแบบภาษา (language design), ทีมพัฒนาคอมไพเลอร์ (compiler implementation), ทีมโครงสร้างพื้นฐาน (infrastructure), ทีมเอกสารคู่มือ (documentation) และอื่นๆ ทีมงานที่เกี่ยวข้องจะทำการอ่านร่างข้อเสนอและความคิดเห็นต่างๆ เพิ่มข้อเสนอแนะส่วนตัวของทีม และในขั้นตอนสุดท้าย จะมีข้อสรุปร่วมกันในการเลือกที่จะยอมรับหรือปฏิเสธฟีเจอร์นั้นๆ

หากฟีเจอร์ดังกล่าวได้รับการตอบรับยอมรับ จะมีการสร้างประเด็นปัญหา (issue) ขึ้นบนคลังเก็บโค้ดของ Rust เพื่อให้นักพัฒนาสามารถเข้ามาอิมพลิเมนต์สร้างระบบขึ้นมาได้ โดยผู้ที่จะมาเขียนโค้ดอิมพลิเมนต์อาจไม่ใช่คนเดียวกันกับที่ยื่นข้อเสนอ RFC ในตอนแรกก็ได้! เมื่อโค้ดพร้อมใช้งานแล้ว มันจะถูกส่งเข้าไปรวมบนสาขาหลักภายใต้การควบคุมสิทธิ์การเปิดใช้ฟีเจอร์ (feature gate) ตามที่เราอธิบายไปในหัวข้อ “คุณลักษณะที่ยังไม่เสถียร”

เมื่อเวลาผ่านไประยะหนึ่ง หลังจากนักพัฒนา Rust ที่ใช้เวอร์ชัน nightly ได้มีโอกาสทดลองใช้งานฟีเจอร์ใหม่นี้แล้ว สมาชิกในทีมจะหารือเกี่ยวกับฟีเจอร์นั้นๆ รวมถึงผลลัพธ์ที่ได้จากการทำงานบน nightly และตัดสินใจร่วมกันว่าควรผลักดันฟีเจอร์นี้เข้าสู่ Rust เวอร์ชันเสถียร (stable) หรือไม่ หากผลตัดสินคือการนำไปใช้งานต่อ ตัวปิดกั้นฟีเจอร์ (feature gate) จะถูกเอาออก และนับแต่นั้นจะถือว่าคุณลักษณะนี้มีสถานะเสถียร (stable)! และจะเดินทางไปตามสายรถไฟซอฟต์แวร์มุ่งสู่รุ่นเสถียรรุ่นใหม่ของ Rust ต่อไป