Gleam OTP – พัฒนาโปรแกรมมัลติคอร์ที่ทนทานต่อความผิดพลาดด้วยสถาปัตยกรรม Actor
(github.com/gleam-lang)- Gleam OTP รองรับการพัฒนาโปรแกรมที่มีความทนทานต่อความผิดพลาดและประสิทธิภาพแบบมัลติคอร์ โดยใช้ โมเดล Actor
- จุดเด่นคือมุ่งเน้น ความปลอดภัยของชนิดข้อมูลแบบสมบูรณ์ และ ความเข้ากันได้กับ Erlang OTP
- มีความสามารถในการกู้คืนจากความขัดข้องและการเยียวยาตนเองผ่าน supervisor
- รองรับเพียงบางส่วนของความสามารถใน Erlang/OTP และ กลยุทธ์การจัดการเพิ่มเติม กำลังอยู่ระหว่างการพัฒนา
- รองรับ Actor หลายประเภท เช่น process, actor, supervisor
ภาพรวมของ Gleam OTP
- Gleam OTP เป็น เฟรมเวิร์ก Actor ที่ทรงพลัง โดยอ้างอิงสถาปัตยกรรม OTP ของ Erlang และเหมาะสำหรับการสร้างโปรแกรมมัลติคอร์ที่ทนทานต่อความผิดพลาด
- เป็นโครงการโอเพนซอร์สที่ใช้ ไลเซนส์ Apache-2.0
คุณสมบัติและข้อดีหลัก
- รับประกัน ความปลอดภัยของชนิดข้อมูลแบบสมบูรณ์ สำหรับ Actor และข้อความ
- ให้ ความเข้ากันได้ กับ Erlang OTP ทำให้ผสานรวมกับสภาพแวดล้อม Erlang เดิมได้ง่าย
- รองรับความทนทานต่อความผิดพลาดผ่าน supervisor เช่น การตรวจจับปัญหา การกู้คืนอัตโนมัติ และการจัดการการยุติการทำงาน
- มุ่งเป้าประสิทธิภาพ ระดับเดียวกับ Erlang OTP
- มี เอกสาร และตัวอย่างให้ใช้งาน ช่วยให้เรียนรู้และนำไปใช้จริงได้ง่าย
คำอธิบายตามประเภทของ Actor
-
process
- ทำหน้าที่เป็นองค์ประกอบพื้นฐานที่สุดใน OTP
- เป็นพื้นฐานของ Actor ประเภทอื่น ๆ แต่ในแอปพลิเคชัน Gleam มักไม่ได้ใช้งานโดยตรงบ่อยนัก
-
actor
- เป็นประเภท process ที่ใช้งานเป็นหลัก และมีความสามารถคล้ายกับ gen_server ของ Erlang
- จัดการข้อความระบบของ OTP โดยอัตโนมัติ พร้อมเปิดใช้ความสามารถด้านการดีบักและการติดตาม
-
supervisor
- ทำหน้าที่เริ่มต้น process อื่น ๆ และรับผิดชอบด้าน การกำกับดูแลและการกู้คืน
- หาก process ลูกเกิดแครชหรือข้อยกเว้น จะถูกเริ่มใหม่โดยอัตโนมัติ
- สร้างโครงสร้างความทนทานต่อความผิดพลาดของแอปพลิเคชันผ่าน การจัดวาง supervisor แบบซ้อนกัน (supervision tree)
- ดูรายละเอียดการติดตั้งใช้งานได้จากเอกสาร
gleam/otp/static_supervisor,gleam/otp/factory_supervisor
ข้อจำกัดและประเด็นที่ควรรู้
- ปัจจุบัน actor ยังไม่รองรับข้อความระบบ OTP ทั้งหมด และจะเพิกเฉยต่อข้อความที่ยังไม่รองรับ
- ความสามารถบางส่วนของ OTP debugging API ยังมีข้อจำกัด
- หากจำเป็น สามารถ เปิด issue เพื่อขอรองรับข้อความที่ยังไม่ได้ติดตั้งใช้งาน
บทสรุปและความสำคัญของโครงการ
- Gleam OTP ขยายจุดแข็งของระบบนิเวศ Erlang มาสู่ภาษา Gleam และมีความสำคัญอย่างมากในแง่ที่ช่วยสร้าง ความปลอดภัยของชนิดข้อมูลและความทนทานต่อความผิดพลาดบนมัลติคอร์ ได้
- เหมาะสำหรับแอปพลิเคชันที่ให้ความสำคัญกับ เสถียรภาพ และ ประสิทธิภาพ ในการใช้งานจริง
- เป็นโครงการโอเพนซอร์สที่มีคุณค่าสูงทั้งต่อการเรียนรู้และการนำไปใช้จริง สำหรับ สตาร์ทอัพ นักพัฒนา IT มืออาชีพ และนักพัฒนาทั่วไป
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ถ้าคุณสนใจภาษาแบบ static type, ไม่มี null, functional และอยู่ในสายภาษา ML ก็แนะนำให้ลอง gleam
และแน่นอนว่ามันรันบน BEAM
ตอนติดตั้ง gleam มีแพ็กเกจประมาณ 50 ตัวถูกติดตั้งลงในระบบของฉัน ซึ่งน่าจะเป็นแพ็กเกจที่เกี่ยวกับ Erlang/Elixir
ถ้าอยาก transpile ไปเป็น JS อย่างเดียวจะเป็นยังไงก็สงสัยอยู่ อาจจะเป็นปัญหาเรื่องแพ็กเกจในระบบของฉันเองก็ได้
ถ้ารองรับ Lua เป็น transpile target ด้วยก็น่าจะดีกว่าอีก สำหรับการฝัง DSL ลงในโปรแกรมอื่น ในความรู้สึกฉัน Lua ง่ายกว่า JS runtime ราว 3 เท่า
ที่สำคัญที่สุด สิ่งที่ดีที่สุดจนถึงตอนนี้คือชุมชน ไลบรารีและเอกสารต่าง ๆ ของชุมชน gleam มีคุณภาพสูงมาก
มันทำให้นึกถึงชุมชน Rust ที่คนเก่ง ๆ จัดการปัญหายาก ๆ ไว้แล้ว เลยมีแนวทางแก้ปัญหาดี ๆ ให้เห็นเยอะมาก (lustre, squirrel ฯลฯ)
อีกจุดเด่นคือมีการทดลองและความคิดสร้างสรรค์ให้เห็นเยอะมาก สิ่งที่ไม่ค่อยเห็นใน ecosystem ภาษาขนาดใหญ่กลับโดดเด่นที่นี่ และบรรยากาศก็เปิดรับมากเมื่อชุมชนกำลังเติบโต
อยากได้คำแนะนำว่าควรเริ่มเรียนจากตรงไหนดี
กำลังหาข้อมูลอยู่ เพราะถ้าใช้ Gleam คู่กับเฟรมเวิร์กแบบ Phoenix ได้ก็คงดีมาก
ตอนนี้กำลังเตรียมโปรเจ็กต์ใหม่ด้วย Python แต่ถ้ามีตัวเลือกที่ใช้ Gleam ได้จริงก็น่าอยากลอง
ข้อดีคือเลือกได้ง่ายมากว่าส่วนไหนจะอยู่ฝั่งฟรอนต์เอนด์หรือแบ็กเอนด์
ลิงก์ YouTube
แต่มีเครื่องมือที่ใช้บ่อยเวลาทำเว็บแอปอยู่
Lustre เป็นเครื่องมือสำหรับ view พื้นฐาน และ Wisp ทำหน้าที่เป็นเซิร์ฟเวอร์
สำหรับ SQL มี squirrel กับ POG (ตัวใหม่แต่กำลังนิยม)
ถ้าคุณต้องการทางเลือกแบบ static type อื่นนอกจาก BEAM มันก็เป็นตัวเลือกที่ดี
มันเป็นภาษาสาย Haskell, ใช้การประเมินผลแบบ strict และรองรับ row polymorphism
เลยอยากรู้ว่าในงานจริงเขาใช้งานมันอย่างไร สร้าง logic ของบริการทั้งหมดด้วยมันเลยหรือใช้แค่บางส่วน
เราผลักแนวทาง "functional core, imperative shell" ไปจนสุดทาง โดยแยกให้ Gleam รับผิดชอบงานคำนวณหนักทั้งหมดจาก codebase Ruby on Rails เดิม
แทบไม่ได้ใช้ฟีเจอร์ของ OTP เลย และปล่อยให้ Rails โฟกัสกับจุดแข็งดั้งเดิมของมันอย่างเว็บ UI/HTTP API
Rails ทำหน้าที่ตั้งค่า input ของ job แล้วข้อมูลของ job จะถูกส่งไปยัง Gleam ผ่าน Redis ในรูปของชุดค่า atomic ชุดเดียว
เราสร้าง wrapper บาง ๆ ด้วย Elixir เพื่อจัดการเฉพาะ network และ file IO ส่วน business logic อยู่ในโมดูล Gleam
ตั้งใจว่าจะเขียนบทความอธิบายเชิงเทคนิคให้ละเอียดกว่านี้เร็ว ๆ นี้ เพราะเป็นหัวข้อที่คนสนใจบน HN บ่อย
Elixir เป็นภาษาที่ดีมากสำหรับงานทั่วไปและมีจุดแข็งในหลายด้าน
ถ้าอยากคุยรายละเอียดเพิ่มเติม ดูวิดีโอ Developer Voices ของฉันได้
ลิงก์ YouTube
มีคนจำนวนมากที่สร้างระบบจริงจังโดยใช้แค่ Erlang/Elixir & BEAM ดังนั้นถ้ามีอะไรสงสัยก็ถามได้และจะมีคนช่วยตอบดี ๆ
พอเข้าใจ OTP ดีพอแล้ว การสร้างทั้งระบบบนมันก็เป็นเรื่องธรรมชาติ
ฉันเองก็ทำแบบนั้นมา 7 ปี แต่ก็พบว่าต้องใช้เวลาพอสมควรกว่านักพัฒนาหน้าใหม่จะคุ้นกับ ecosystem นี้
ฉันไม่เห็นความจำเป็นที่จะต้องใส่เรื่องการเมืองลงในหน้าโปรเจ็กต์ด้านเทคนิค
ไม่ใช่เรื่องเห็นด้วยหรือไม่เห็นด้วย แต่ฉันคิดว่าในพื้นที่แบบมืออาชีพควรตัดการถกเถียงแบบนี้ออกไป
ไม่อย่างนั้นบทสนทนาจะหลุดประเด็นโดยไม่จำเป็น
"Black lives matter. Trans rights are human rights. No nazi bullsh*t."
ถ้าคุณตัดสินใจว่าจะไม่ใช้เพราะประโยคเดียวนี้ ฉันก็คิดว่ามันทำงานได้ตรงตามเจตนาแล้ว
แต่ดูเหมือนว่าคุณเองต่างหากที่เป็นคนทำให้มันหลุดประเด็น
ถ้าเป็นเรื่อง fault tolerance และ multicore ฉันคิดว่าการใช้ software transactional memory กับ functional effect system แบบ Scala/ZIO ดีกว่า
แน่นอนว่าถ้ายังมีกรณีที่ต้องใช้ actor model ก็ยังใช้ได้
อีกอย่าง เมื่อดูจากความสุกงอมของ ecosystem บน JVM, observability และความพร้อมใช้งานจริง มันก็ดูเหนือกว่า BEAM
จะวิจารณ์จุดอ่อนของ BEAM ก็เข้าใจได้ แต่การวิจารณ์ในจุดที่เป็นจุดแข็งของมันกลับดูไม่ค่อยใช่
BEAM ออกแบบมาให้ส่งข้อความแบบ immutable ระหว่าง green thread ที่เบาและราคาถูกมาก
มันมีระบบกำกับดูแลที่แข็งแรงอย่าง supervisor trees ทำให้ไม่ต้องกังวลเรื่อง data race หรือ thread ค้าง
ทั้งหมดนี้มีมาให้ในตัวจึงแทบไม่มี boilerplate
และด้วยความเป็น immutable ประสิทธิภาพก็ดีกว่าที่หลายคนคิด
สุดท้ายแล้ว BEAM คือแพลตฟอร์มที่เหมาะที่สุดสำหรับระบบ distributed/concurrent ที่ต้องการ fault tolerance
ปัจจัยสำคัญอย่างหนึ่งที่ทำให้ทนทานได้ขนาดนั้นคือ robust supervising และโครงสร้างพื้นฐานข้ามเครื่อง
มันเป็นภาษาที่สร้างแรงบันดาลใจสำคัญให้ระบบ actor ถือได้ว่า Erlang มีอยู่เพื่อสิ่งนี้โดยเฉพาะ และทำได้ดีมากจริง ๆ
ถ้าข้อมูลนั้นจำเป็นต้องแชร์จริง ๆ มันก็ต้องเป็นข้อมูลแบบ immutable เท่านั้น
เท่าที่ฉันนึกออกมีแค่งานคำนวณเชิงตัวเลขที่หนักมาก ๆ แต่กรณีนั้นก็ไม่เขียนด้วย elixir หรือ erlang ตรง ๆ อยู่แล้ว แค่ทำเป็น NIF ก็พอ
ต่อให้ไม่ได้ใช้ actor pattern แบบชัดเจน เรื่องการส่งต่อ state หรือการประสานงานก็เป็นปัญหาที่ถูกแก้ไว้แล้ว
มี primitive พื้นฐานอย่าง task, agent, GenServer, Supervisor ครบอยู่แล้ว