ชุมชน Rust กำลังพูดถึง Subsecond ไลบรารี hot-patching ตัวใหม่ที่สัญญาว่าจะเร่งรอบการพัฒนาได้อย่างมาก ต่างจากเวิร์กโฟลว์แบบ edit-compile-run ดั้งเดิมที่อาจใช้เวลาหลายนาที เครื่องมือนี้อ้างว่าสามารถทำ patch ได้เร็วถึง 130 มิลลิวินาทีบนโปรเซสเซอร์ M4 ของ Apple
เมตริกประสิทธิภาพ:
- เวลาคอมไพล์-แพตช์: 130ms (บนโปรเซสเซอร์ Apple M4 )
- เวลาบิลด์แบบเพิ่มหน่วย: ต่ำกว่า 500ms (ด้วย ThinLink )
- เป้าหมาย: โหมดการพัฒนาเท่านั้น (เปิดใช้งาน debug_assertions )
การอ้างสมรรถนะดึงดูดความสนใจ
วิดีโอสาธิตของผู้สร้างแสดงผลลัพธ์ที่น่าประทับใจในเฟรมเวิร์กต่างๆ การรวมเข้ากับ game engine Bevy การพัฒนา iOS และแม้แต่แอปพลิเคชัน full-stack ที่มี backend Axum ล้วนแสดงการอัปเดตโค้ดแบบเกือบทันที การปรับปรุงความเร็วนี้ดึงดูดความสนใจของนักพัฒนา โดยเฉพาะผู้ที่ทำงานกับแอปพลิเคชันที่รันนานๆ ซึ่งการรีสตาร์ทจะทำให้สูญเสีย state ที่มีค่า
ระบบทำงานโดยการดักจับขั้นตอน linking ของ Rust และขับเคลื่อนคอมไพเลอร์ด้วยตนเอง มันเปรียบเทียบโค้ด assembly ระหว่างการคอมไพล์ ระบุการเปลี่ยนแปลง และ patch symbols กับกระบวนการที่กำลังรัน วิธีการนี้รองรับแพลตฟอร์มหลักรวมถึง macOS, Windows, Linux, iOS, Android และ WebAssembly
การรองรับแพลตฟอร์ม:
- Android (arm64-v8a, armeabi-v7a)
- iOS (arm64, รองรับเฉพาะ simulator - ไม่รองรับอุปกรณ์จริงเนื่องจากข้อจำกัดเรื่อง code-signing)
- Linux (x86_64, aarch64)
- macOS (x86_64, aarch64)
- Windows (x86_64, arm64)
- WebAssembly (wasm32)
ข้อกำหนดการแก้ไขโค้ดได้รับปฏิกิริยาแบบผสม
ข้อจำกัดหลักของไลบรารีนี้ได้จุดประกายการถกเถียงในชุมชน นักพัฒนาต้อง wrap ฟังก์ชันที่ต้องการ hot-patch ด้วย subsecond::call()
ซึ่งบางคนมองว่าเป็นการรบกวน นักวิจารณ์โต้แย้งว่าข้อกำหนดนี้ทำให้เครื่องมือดูน่าสนใจน้อยลงเมื่อเทียบกับโซลูชันในภาษาอื่นที่สามารถแก้ไขฟังก์ชันใดๆ ได้โดยไม่ต้องมี annotation พิเศษ
อย่างไรก็ตาม ผู้สนับสนุนชี้ให้เห็นว่าการรวมเข้ากับเฟรมเวิร์กสามารถซ่อนความซับซ้อนนี้ได้ เฟรมเวิร์กยอดนิยมอย่าง Dioxus และ Bevy ได้สร้างการรองรับ Subsecond เข้าไปในระบบหลักของพวกเขาแล้ว หมายความว่าผู้ใช้ปลายทางจะได้ hot-patching โดยไม่ต้องตั้งค่าด้วยตนเอง
สิ่งที่ฉันต้องการ hot reloading นั้นน้อยกว่า 5% ของโค้ดเบสทั้งหมด มันมักจะเป็นสิ่งที่ฉันไม่สามารถ debug ได้ (เช่น: API response) ดังนั้นฉันจึงต้องไปมาคอมไพล์ซ้ำ หากฉันสามารถได้ hot-reloading สำหรับสิ่งนั้น นั่นคือการปรับปรุงเวลา 95% สำหรับฉัน
ความท้าทายทางเทคนิคและข้อกังวลด้านความปลอดภัย
ระบบเผชิญกับอุปสรรคทางเทคนิคหลายประการที่ได้สร้างการอภิปราย การเปลี่ยนแปลง struct layout ไม่ได้รับการรองรับ ซึ่งหมายความว่าเฟรมเวิร์กต้องทิ้ง state เก่าเมื่อโครงสร้างเปลี่ยนแปลง วิธีการนี้แตกต่างจากระบบ hot-reloading ที่ซับซ้อนกว่าอย่าง OTP ของ Erlang ซึ่งสามารถอัปเกรด internal state ระหว่างการเปลี่ยนแปลงโค้ดได้
Thread-local variables เป็นความท้าทายอีกประการหนึ่ง ปัจจุบันพวกมันจะรีเซ็ตเป็นค่าเริ่มต้นใน patch ใหม่ ซึ่งอาจทำให้เกิดการ crash ในการตั้งค่าที่ซับซ้อน ผู้สร้างยอมรับข้อจำกัดนี้และวางแผนแก้ไขในอนาคต
ไลบรารีทำงานได้เฉพาะใน debug mode เพื่อให้มั่นใจว่าไม่มี performance overhead ใน production builds การเลือกออกแบบนี้เสริมว่า Subsecond มุ่งเป้าไปที่เวิร์กโฟลว์การพัฒนามากกว่าสถานการณ์ hot-patching ใน production
ข้อจำกัดสำคัญ:
- ไม่รองรับการเปลี่ยนแปลงโครงสร้าง struct (ต้องทำการสร้าง framework ใหม่)
- ตัวแปร thread-locals จะถูกรีเซ็ตกลับไปเป็นค่าเริ่มต้นเมื่อมีการแพตช์
- แพตช์เฉพาะ "tip" crate (ตำแหน่ง main.rs) เท่านั้น
- การรองรับ workspace มีข้อจำกัด
- ไม่สามารถตรวจจับการเปลี่ยนแปลงของ static initializer
การรับเอาของเฟรมเวิร์กและแผนอนาคต
การรับเอาในช่วงแรกโดยเฟรมเวิร์ก Rust หลักบ่งบอกว่าเครื่องมือนี้อาจได้รับการยอมรับในวงกว้างมากขึ้นแม้จะมีข้อจำกัด ทีม Dioxus ซึ่งเป็นผู้สร้าง Subsecond ได้รวมมันเข้าไปใน web framework ของพวกเขา นักพัฒนา Bevy กำลังสำรวจการรวมเข้าโดยใช้ระบบ reflection ของพวกเขาเพื่อจัดการ struct hot-reloading อย่างสง่างามมากขึ้น
แผนสำหรับ general-purpose adapters สำหรับไลบรารียอดนิยมอย่าง Axum, Ratatui และ Egui อาจขยายการรับเอา ผู้สร้างยังกล่าวถึงการรวมอัตโนมัติที่เป็นไปได้ในระดับที่ต่ำกว่า อาจมุ่งเป้าไปที่ dependencies ที่แพร่หลายเพื่อลดข้อกำหนดการตั้งค่าด้วยตนเอง
โปรเจกต์นี้แสดงถึงก้าวสำคัญสู่รอบการพัฒนา Rust ที่เร็วขึ้น แม้ว่าจะต้องการการปรับเปลี่ยนเวิร์กโฟลว์บ้าง สำหรับนักพัฒนาที่ใช้เวลามากในลูป compile-test การแลกเปลี่ยนอาจคุ้มค่า
อ้างอิง: Crate subsecond