เส้นทางสู่ Dune ระบบบิลด์ที่ดีกว่าสำหรับ OCaml
(blog.janestreet.com)- Jane Street สร้าง Jenga ขึ้นมาจากความไม่พอใจต่อ OMake แต่การนำไปใช้นอกองค์กรมีไม่มาก ส่วน Jbuilder ที่สร้างเป็นชั้นความเข้ากันได้กลับเติบโตเกินคาดจนกลายเป็นเครื่องมือพื้นฐานของคอมมูนิตี้ OCaml
- จุดดึงดูดช่วงแรกของ Jbuilder ไม่ใช่ฟีเจอร์ แต่เป็น ความเร็วและความพกพาข้ามแพลตฟอร์ม และในโปรเจกต์ของ Jane Street การคอมไพล์ที่เร็วกว่า OCamlbuild ประมาณ 5 เท่า เป็นปัจจัยสำคัญที่ทำให้ถูกนำไปใช้
- Jbuilder พัฒนาเป็นระบบบิลด์เต็มรูปแบบจากความร่วมมือกับ OCaml Labs และหลังการหารือในคอมมูนิตี้ก็เปลี่ยนชื่อเป็น Dune เพราะชื่อเดิมชนกับ Java IDE ของ Borland
- Jane Street ดูแล Jenga และ Dune ควบคู่กันอยู่ช่วงหนึ่ง แต่เมื่อโค้ดเบสเติบโตเป็น OCaml 65 ล้านบรรทัด และ Python 5 ล้านบรรทัด ความยากในการย้ายภายในก็เพิ่มขึ้นมาก
- หลังจากทุ่มงานนานกว่าหนึ่งปี โค้ดเบสของ Jane Street ก็ถูกบิลด์ด้วย Dune และบิลด์ที่แคชส่วนใหญ่ถูกเติมไว้แล้วเร็วขึ้น 2~3 เท่า
Jenga ที่เริ่มจากความไม่พอใจต่อ OMake
- ระบบบิลด์เป็นเครื่องมือประจำวันที่นักพัฒนาใช้สร้างโปรแกรมที่รันได้จากไฟล์ซอร์สหลายไฟล์ รวมถึงจัดการการเรียกคอมไพเลอร์และการรันทดสอบ
- ราวปี 2012 Jane Street ไม่พอใจกับ OMake ซึ่งเป็นหนึ่งในระบบบิลด์มาตรฐานของ OCaml ในเวลานั้น จึงสร้างระบบบิลด์ของตนเองชื่อ Jenga
- เนื่องจาก Jenga ทำงานได้ดีภายในองค์กร Jane Street จึงตัดสินใจเปิดเผยต่อสาธารณะ โดยมองว่าคอมมูนิตี้ก็น่าจะนำไปใช้ได้อย่างมีประโยชน์
- คาดหวังให้ผู้ใช้ภายนอกลองใช้ Jenga และร่วมสนับสนุนการพัฒนา
- มองว่าจะช่วยให้การเปิดซอร์สโค้ดของ Jane Street เป็นโอเพนซอร์สทำได้ง่ายขึ้นด้วย
- แต่การนำไปใช้งานภายนอกจริงไม่ถึงระดับที่คาดหวัง
- ไม่ทำงานบน Windows
- การนำ Jenga ไปใช้แทบจะหมายถึงต้องยอมรับ แนวทางของ Jane Street ทั้งหมดในการบิลด์ OCaml
- เมื่อการใช้งานภายนอกไม่เพิ่มขึ้น Jane Street จึงนำ Jenga กลับไปเป็นโครงการไม่เปิดเผยอีกครั้ง และปัญหาเรื่องการบิลด์โค้ดโอเพนซอร์สยังคงอยู่
Jbuilder ที่สร้างขึ้นเป็นชั้นความเข้ากันได้
- ในปี 2016 Jane Street ตัดสินใจสร้าง Jbuilder ซึ่งเป็นเครื่องมือข้ามแพลตฟอร์มแบบเรียบง่าย เพื่อให้ผู้ใช้ภายนอกบิลด์โค้ดของบริษัทได้โดยไม่ต้องรับ Jenga ทั้งชุด
- เครื่องมือนี้ยังมีเป้าหมายเพื่อลดภาระในการเขียนบิลด์ใหม่ให้เข้ากับ OCamlbuild ซึ่งในเวลานั้นกำลังกลายเป็นมาตรฐานใหม่สำหรับการบิลด์โปรเจกต์ OCaml
- Jbuilder เข้าใจไฟล์
jbuildที่ Jenga ใช้สำหรับตั้งค่าการบิลด์ และรันคำสั่งคอมไพล์ที่จำเป็นตาม ลำดับโทโพโลยี - Jbuilder ช่วงแรกยังห่างไกลจากระบบบิลด์ในความหมายทั่วไป
- ไม่ได้เลือกแค่คำสั่งที่อินพุตเปลี่ยนแปลงมารันใหม่
- ใช้วิธีรันคำสั่งทั้งหมดใหม่ทุกครั้ง
กระบวนการที่ Jbuilder กลายเป็น Dune
- เดิมที Jbuilder ตั้งใจให้เป็นชั้นความเข้ากันได้ขนาดเล็ก แต่ผู้ใช้เริ่มนำไปใช้บิลด์โปรเจกต์ของตนเอง นอกเหนือจากแพ็กเกจของ Jane Street
- ปัจจัยใหญ่ที่สุดที่ผลักดันการนำไปใช้คือ ความเร็ว
- เร็วกว่า OCamlbuild ประมาณ 5 เท่า ในการคอมไพล์โปรเจกต์ของ Jane Street
- มีความพกพาข้ามแพลตฟอร์มที่ดี
- โครงสร้างเรียบง่าย จึงแก้ไขได้ง่าย
- Jane Street เริ่มร่วมมือกับ OCaml Labs ซึ่งปัจจุบันคือ Tarides เพื่อพัฒนา Jbuilder ให้เป็นระบบบิลด์ที่สมบูรณ์ยิ่งขึ้น
- ชื่อกลายเป็นอีกประเด็นหนึ่ง
- มี JBuilder ซึ่งเป็น Java IDE ของ Borland อยู่แล้ว
- แม้ระบบนั้นแทบจะหายไปนานแล้ว แต่เมื่อสอบถามเจ้าของลิขสิทธิ์ถึงความตั้งใจจะใช้ชื่อ ก็ไม่ได้รับอนุญาต
- หลังการหารือในคอมมูนิตี้ จึงเลือกชื่อใหม่เป็น Dune
- การหารือที่เกี่ยวข้องเกิดขึ้นใน เธรดเสนอชื่อใหม่สำหรับ Jbuilder
ต้นทุนของการดูแลระบบบิลด์สองระบบควบคู่กัน
- เมื่อ Dune ได้รับความนิยมมากขึ้น Jane Street จึงต้องดูแลและสนับสนุนระบบบิลด์เต็มรูปแบบที่บริษัทสร้างเองพร้อมกันสองระบบ คือ Jenga และ Dune
- Dune กลายเป็นระบบที่มีโครงสร้างซึ่งออกแบบใหม่ มีประสิทธิภาพรวดเร็วในการบิลด์ของผู้ใช้ส่วนใหญ่ ถูกนำไปใช้อย่างกว้างขวางกว่า และมี API กับประสบการณ์ผู้ใช้ที่ดีกว่า
- คำถามว่าจะย้ายระบบภายในไปใช้ Dune เมื่อใดจึงกลายเป็นโจทย์ตามธรรมชาติ แต่ทีมระบบบิลด์ก็ยุ่งอยู่แล้วกับการตามให้ทันโค้ดเบสที่เติบโตขึ้น
- ตอนที่ Dune เริ่มต้นในปี 2016 โค้ด OCaml มี 4 ล้านบรรทัด
- ปัจจุบันมี OCaml 65 ล้านบรรทัด และ Python 5 ล้านบรรทัด
- การย้ายไป Dune มีภาระสูงจนยังไม่สามารถเริ่มทำอย่างจริงจังได้ และมีเพียงการประเมินเชิงหวังดีซ้ำ ๆ ว่า “อาจเป็นไปได้ภายใน 6~12 เดือนข้างหน้า”
- ปีที่แล้ว Jane Street เพิ่มทีมระบบบิลด์เป็น วิศวกรฟูลไทม์ 5 คน แล้วจึงเริ่มงานย้ายที่เลื่อนมานาน
Dune ที่แทนที่ Jenga ภายใน Jane Street
- หนึ่งในงานใหญ่ที่สุดคือทำให้ Dune สเกล ได้เหมาะกับโค้ดเบสขนาดมหึมาของ Jane Street
- เหตุผลหนึ่งที่ Dune เร็วเมื่อใช้งานภายนอก คือผู้ใช้ส่วนใหญ่บิลด์โปรเจกต์ที่เล็กกว่า รีโพซิทอรี 70 ล้านบรรทัด ของ Jane Street มาก
- Jenga เองก็ไม่ได้หยุดนิ่งตลอด 10 ปี
- Jane Street ปรับปรุงการใช้งานจริงของ Jenga ต่อเนื่องให้สอดคล้องกับการเติบโตของโค้ดเบส
- Jenga อยู่ในสภาพที่ถูกปรับแต่งอย่างมากสำหรับความต้องการของ monorepo ขนาดใหญ่
- งานปรับแต่งจำนวนมากนี้ต้องถูกย้ายไปยัง Dune
- งานอินทิเกรตในชีวิตประจำวันก็ไม่ง่าย
- ระบบบิลด์ถูกเรียกใช้จากหลายเวิร์กโฟลว์
- เอดิเตอร์สามตัวคือ Vim, Emacs และ VSCode ต่างมีการอินทิเกรตแบบคัสตอมสำหรับ Jenga
- ต้องย้ายการอินทิเกรตแต่ละส่วนไปยัง Dune ทีละอย่าง
- หลังจากทุ่มงานนานกว่าหนึ่งปี ตอนนี้โค้ดเบสของ Jane Street ถูกบิลด์ด้วย Dune แล้ว
- ณ จุดเปลี่ยนผ่าน ประสิทธิภาพของ Dune โดยรวมเท่ากับหรือดีกว่า Jenga
- ในบางกรณีแสดงประสิทธิภาพที่ดีกว่ามาก
- เมื่อบิลด์ส่วนใหญ่มีอยู่ในแคชแล้ว การบิลด์เร็วขึ้น 2~3 เท่า
การปรับปรุงถัดไปที่ทำได้บนระบบเดียว
- Jane Street มีแผนเปิดโอเพนซอร์สงานปรับปรุงประสิทธิภาพ Dune เป็นส่วนใหญ่ และบางส่วนเปิดเผยแล้ว
- เพื่อไม่ให้เกิดสองระบบขึ้นมาอีก คือ Dune fork สำหรับ Jane Street และ Dune ภายนอก Jane Street ให้ความสำคัญกับการส่งการเปลี่ยนแปลงที่ทำได้กลับไปยัง upstream
- Dune กลายเป็นฐานที่เหมาะสมยิ่งขึ้นสำหรับการสร้างฟีเจอร์ใหม่
- โค้ดเบสเรียบง่ายกว่าและทำงานด้วยง่ายกว่า
- สามารถโฟกัสกับระบบเดียวได้
- ฟีเจอร์ต่อไปนี้ก็ใกล้เข้ามามากขึ้น
-
บิลด์แบบกระจาย
- shallow build หรือ “builds without the bytes”
- การโหลดแคชของกราฟบิลด์เอง
- ทีมระบบบิลด์เติบโตเป็น วิศวกรฟูลไทม์ 12 คน ในนิวยอร์ก ลอนดอน และสิงคโปร์ และความเร็วในการปรับปรุง Dune ก็เพิ่มขึ้นด้วย
-
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ข้อความตอนแครช ของ Dune:
https://github.com/ocaml/dune/issues/2767
พอดแคสต์ด้านเทคโนโลยีของ Jane Street ชื่อ Signals and Threads มีตอนหนึ่งในปี 2020 ที่พูดถึง build system ขอแนะนำอย่างแรง
ตอนอื่น ๆ ก็ดีเช่นกัน โดยเฉพาะ The Future of Programming ที่มี Richard Eisenberg และ What is an Operating System? ที่มี Anil Madhavapeddy ก็แนะนำด้วย
¥https://signalsandthreads.com/build-systems/
°https://signalsandthreads.com/future-of-programming/
§https://signalsandthreads.com/what-is-an-operating-system/
https://signalsandthreads.com/multicast-and-the-markets/
น่านับถือที่ Jane Street พิสูจน์ให้เห็นว่า functional programming แบบ HM type ก็พร้อมใช้ใน production และเร็วมากได้ หากทุ่มเทมากพอ
ยังได้ยินเป็นครั้งคราวว่าภาษา functional ที่มีสไตล์เชิงวิชาการมากกว่ายังใช้ใน production ไม่ได้ แต่ OCaml แสดงให้เห็นว่าเป็นไปได้แม้มีข้อกำหนดด้านประสิทธิภาพสูง
https://mercury.com/
เป็นตัวเลือกที่ยอดเยี่ยมสำหรับสร้างโปรแกรมคุณภาพสูง พร้อม interoperable กับระบบเดิมได้กว้างขวาง
ตามบล็อกโพสต์เมื่อหลายปีก่อน พวกเขาเคยลอง Roc ด้วย แต่ไม่รู้ว่าตอนนี้ยังใช้อยู่ไหม
[0] https://blog.noredink.com
ทุกครั้งที่อ่านบล็อกของ Janestreet ผมแอบหัวเราะในใจว่า การทำงานด้านการเงินที่ Jane ดูเหมือนจะสนุกกว่าและให้ผลตอบแทนดีกว่างานในสิ่งที่เรียกว่าอุตสาหกรรมเทคโนโลยี 90% เสียอีก
งานเทคโนโลยีในภาคการเงินจำนวนมากไม่ได้สนุกหรือจ่ายดีเท่าแม้แต่บริษัทเทคโนโลยีทั่วไป ไม่ต้องพูดถึง Jane Street เลย
งานจำนวนมากในภาคการเงินคือการแก้ โค้ด Java อายุ 20 ปี หรือหาวิธีใหม่ ๆ ในการใส่ข้อมูลเข้าและดึงข้อมูลออกจากไฟล์ Excel เพื่อทำรายงานเฉพาะทาง
และได้ยินมาว่าการเข้า JS ยากกว่า Google/Meta มาก
ผมเองก็เคยสมัครเมื่อก่อน ผู้สัมภาษณ์ค่อนข้างไม่น่าประทับใจในทางลบ และไม่เคยเจอแบบนั้นในการสัมภาษณ์กับ big tech เลย จึงไม่ใช่ความประทับใจที่ดีนัก
ถึงอย่างนั้นก็ยังให้ค่ามากกว่างานทำให้คนคลิกโฆษณา
ก็เหมือนบริษัทอื่น ๆ คือมีทั้งโปรเจกต์ที่น่าสนใจและงานน่าเบื่อปะปนกัน
สิ่งเดียวที่แย่กว่า codebase ที่ซับซ้อนคือ build system ที่ซับซ้อน CMake น่ารังเกียจมาก
เหมือนกับว่า “ถ้าจะคอมไพล์ภาษานี้ ก็จงเรียนภาษาใหม่อีกภาษาหนึ่ง!”
มันก็มีบางอย่างที่ทำได้ถูกต้อง และบางอย่างที่ทำผิดก็ยังพอจัดการได้
ถ้าได้ขั้นตอน build หลายแพลตฟอร์มจากชุดไฟล์ config ที่มนุษย์แก้ไขได้ ก็ยอมทนความเจ็บปวดได้ในระดับหนึ่ง
ภาษาสคริปต์ที่ย่ำแย่คอยถ่วงไว้ แต่ถ้ามีแรงจูงใจเพียงพอก็อาจปรับปรุงได้
เมื่อก่อน หลังจาก Lisp ประสบการณ์สาย functional ครั้งแรกของผมคือใช้เวลาอยู่กับฝั่ง Haskell หลายปี
OCaml ไม่ค่อยเข้าถึงผมเท่าไร และผมมี อาการแพ้เซมิโคลอน แบบหายากด้วย เลยรู้สึกว่า Haskell ดูดีกว่ามาก
แต่พอช่วงหลังได้ลองใช้ Reason แล้วชอบมาก จู่ ๆ ทุกอย่างที่เกี่ยวกับ OCaml ก็น่าสนใจขึ้นมา
https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
https://ocaml.org/docs/toplevel-introduction#loading-librari...
https://reasonml.github.io/ ดูเท่ดี เหมือน OCaml ที่มีกลิ่น JavaScript
ถ้าเข้าใจเส้นแบ่งนั้นแล้วก็คงไม่เป็นไร แต่ดูเหมือนต้องเรียนรู้การคิดด้วยโครงสร้างแบบนั้น เหมือนกับ Lisp ถึงอย่างนั้นพอมีโค้ด Haskell เต็มหน้าจอก็ยังรู้สึกกลัวอยู่ดี
ในบรรดาพวกนั้น SML/NJ อ่านง่ายที่สุดสำหรับผม
อยากรู้ว่ามีใครเคยใช้ ไลบรารีและเครื่องมือ OCaml แบบโอเพนซอร์สของ Jane Street ในโปรเจกต์ที่ค่อนข้างจริงจังบ้างไหม
จากที่ลองดูคร่าว ๆ รู้สึกว่าพวกเขาทุ่มแรงมากในการสร้าง ecosystem และเปิดซอร์สโค้ด แต่ยังไม่เหมือนอยู่ในสภาพที่ “พร้อม” ให้คนนอก Jane Street ใช้
ถ้าจะหาอะไรสักอย่าง คุณต้องอ่าน signature ของฟังก์ชันได้ค่อนข้างคล่อง แต่นอกนั้นก็ไม่มีอะไรให้บ่น เช่น ฟังก์ชันแปลงไป-กลับกับ s-expression สำหรับ basic type ทุกชนิด ถ้ารู้ว่ามีอยู่และวางแผนไว้ล่วงหน้า จะช่วยประหยัดเวลาได้มหาศาล
ผมเคยใช้ไลบรารีอื่น ๆ ด้วย และ ppx สำหรับ logging กับ unit test ก็แทบจะเป็นมาตรฐานโดยพฤตินัยในโลก OCaml ถ้าของแบบนั้นเป็นไปได้ในโลกนี้ ผมเคยใช้ code formatter, test framework ตัวหนึ่ง และ implementation ของ data structure ขั้นสูงด้วย
บางครั้งก็เจอของที่ใช้งานไม่ได้จริง ๆ เหมือนที่คอมเมนต์อื่นว่าไว้ เช่น ไปพึ่งพาอะไรบางอย่างที่แยกแจกและไม่มีเอกสาร หรือจำเป็นต้องมีการตั้งค่าลับบางอย่าง ไม่ได้มีเจตนาร้าย และถ้าเปิด issue ไว้แล้วกลับมาดูอีก 1–2 ปีให้หลัง ก็มักจะใช้งานได้แล้ว
ไม่ใช่ว่าไม่มีความหงุดหงิดเลย แต่ผมชื่นชมแนวทางที่เปิดออกมาทั้งหมด แทนที่จะเอาทรัพยากรไปทดสอบและขัดเกลา release จำนวนน้อยกว่า คุณภาพโค้ดโดยรวมสูงมาก และถึงจะรันเองไม่ได้ ก็ยังเป็น implementation ตัวอย่างที่เข้มงวดและผ่านการพิสูจน์มาแล้ว
ผมว่า API ดีกว่า stdlib มาตรฐานมาก
ผมชอบ Lean 4 แต่ให้ AI ช่วยไม่ค่อยง่าย งานที่กำลังทำวันนี้คือย่อย reference manual ให้ใส่ใน context window 200K ได้พอดี จะดูว่าจะช่วยได้ไหม
ค่อนข้างแปลกใจที่การพัฒนาระบบ build ใหม่เองแล้ว migrate ไปใช้ ยังสมเหตุสมผลกว่าการนำเครื่องมือสำเร็จรูปอย่าง buck2 หรือ bazel มาใช้
ไม่ได้หมายความว่า build tool ขั้นสูงพวกนี้นำมาใช้ได้ง่าย แต่ถ้าเทียบกับการทำเองล่ะ? อยากรู้ว่ามีอะไรพิเศษที่ทำให้ dune แตกต่างมากไหม
Bazel release แรกออกปี 2015 ส่วน Buck ออกปี 2013
JS มีวัฒนธรรม NIH อยู่บ้าง แต่ไม่รู้ว่าในกรณีนี้มีผลหรือเปล่า ตอนนั้น build tool ดี ๆ มีไม่มาก โดยเฉพาะสำหรับบริษัทที่ใช้ tech stack ไม่ค่อยดั้งเดิมยิ่งเป็นแบบนั้น
โดยเฉพาะเหมือนต้องสามารถรัน ocamldep ล่วงหน้าได้ หรือไม่ก็ต้องคอมไพล์สองรอบ ซึ่ง buck2 ทำได้ ส่วน Bazel เท่าที่จำได้ต้อง hack
ทั้งสองคล้ายกันคร่าว ๆ ความเร็วล้วน ๆ ในการเรียก OCaml build tool นั้น dune เร็วกว่า แต่เมื่อจำเป็นต้อง rebuild หลายอย่างและใช้ distributed build system buck2 จะชนะ
ความเจ็บปวดใหญ่คือการ integrate กับ LSP เพราะวิธีเดียวที่ LSP server จะรู้ dependency ของไฟล์ได้คือผ่านการ build จึงต้องผูกแน่นกับ build system ใน dune ทุกอย่างถูกจัดมาอย่างเรียบร้อย ส่วนกับ buck2 เราก็พอเชื่อมให้ทำงานได้ แต่ไม่ได้ดีเท่านั้น
Dune เป็นชื่อ build system ที่ดีที่สุดแบบขาดลอย ไม่มีอะไรเข้าใกล้เลย
เริ่มจากตั้งใจจะสร้าง build system ที่ดีกว่า แล้ว “บังเอิญ” ได้สร้าง build system ที่ดีกว่าขึ้นมาจริง ๆ วิธีเกิดของความบังเอิญแบบนี้นี่แปลกดี