Async Rust ด้วย Tokio — Rust Systems IV
ต่อจาก Rust Systems III (#23): สามคอร์สแรกของซีรีส์ Rust จงใจไม่แตะ async เลย และ kaen-kvstore ของ #22 รับคอนเนกชันด้วย ThreadPool ขนาดคงที่ 4 worker ที่หนึ่งคอนเนกชันยึด worker ไว้ทั้งเส้น ปัญหาจึงไม่ใช่ thread เยอะเกิน แต่คือ worker ถูก block ทิ้งไว้ระหว่างรอ I/O — คอร์สนี้เปิดประตู async จริงเป็นครั้งแรก และเป็นคอร์ส Rust ตัวแรกของเว็บที่ crate dependency เป็นแกนของทุกบท (tokio 1.53.1 บน rustc 1.97.1 edition 2024 — #22 กับ #23 เป็น zero-crate จริง ส่วน #21 มี clap/serde/thiserror อยู่แล้ว) เริ่มจากข้อเท็จจริงที่กัดที่สุด: เรียก async fn ใน Rust แล้วไม่มีอะไรรันเลย เพราะ Future เป็น state machine แบบ lazy — เราจะพิสูจน์ด้วยการเขียน executor เองราว 15 บรรทัดด้วย std ล้วน (poll / Poll / Waker / Pin) → แล้วค่อยเปลี่ยนมาใช้ Tokio runtime ตัวจริงที่รวม executor + reactor (epoll ผ่าน mio) + timer ไว้ด้วยกัน → แตกงานเป็น task ด้วย spawn และ JoinHandle → เขียน async I/O กับ TCP ที่รับคอนเนกชันจำนวนมากได้โดยไม่ต้องยึด OS thread ไว้หนึ่งตัวต่อหนึ่งคอนเนกชัน → แข่ง future ด้วย select! และเข้าใจว่า "ยกเลิก" ในโลก async แปลว่า drop → share สถานะข้าม task ด้วย Send, Mutex และ channel ที่มี backpressure → เก็บกวาดกับดักคลาสสิก (guard ค้างข้าม .await, block runtime, function colouring) → ปิดท้ายด้วย capstone ที่ยก kaen-kvstore จาก #22 ขึ้นมาอยู่บน Tokio พร้อม graceful shutdown ครบวงจร ต่างจาก #23 ที่คงเรื่อง consensus ไว้เป็นกล่องไดอะแกรม คอร์สนี้ไม่มีบทไหนเป็นไดอะแกรมอย่างเดียวเลย — ทุก snippet compile และรันได้จริงในแซนด์บ็อกซ์ (ยกเว้น snippet ที่ติดป้าย ❌ ซึ่งตั้งใจให้พัง และการกด Ctrl-C จริงที่จำลองด้วย mpsc) 8 บทลงมือจริง