2 คะแนน โดย GN⁺ 2024-03-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในระบบนิเวศ Rust ทันทีที่ dependency ที่หยุดดูแลรักษาถูกขึ้นทะเบียนใน RUSTSEC แม้แต่ไลบรารีที่ไม่ได้มีปัญหาโดยตรงก็กลายเป็นหนี้ทางเทคนิคผ่านผู้ใช้และ CI
  • insta พึ่งพา yaml-rust ซึ่งหลังจากผู้เขียนเดิมลดความสนใจลง ก็อยู่ในสภาพที่มี คำขอฟีเจอร์และบั๊ก สะสมอยู่
  • หลังจากถูกขึ้นทะเบียนใน RUSTSEC ทำให้ CI ของผู้ใช้ทั้งทางตรงและทางอ้อมล้มเหลว หากเปรียบเทียบกับการเงิน ก็เหมือนเกิด การลดอันดับเครดิต และ margin call
  • ไลบรารีทดแทนหรือ fork ก็ไม่ใช่ทางออกที่ชัดเจน ดังนั้นแม้เปลี่ยน dependency ก็ยังเหลือภาระการดูแลรักษาและความเสี่ยงจาก dependency ใหม่
  • ทางรับมือสุดท้ายคือการ vendoring โค้ด yaml-rust เข้าไปใน insta และนำไปสู่คำวิจารณ์ว่าใกล้เคียงกับ CDO ที่ห่อหนี้ทางเทคนิคคุณภาพต่ำให้ดูเป็น AAA

กระบวนการที่ dependency yaml-rust ถูกเปิดเผยว่าเป็นหนี้ทางเทคนิค

  • insta พึ่งพา yaml-rust และ yaml-rust อยู่ในสภาพที่ issue สะสมต่อเนื่องหลังจากผู้เขียนเดิมหมดความสนใจ
    • บางส่วนเป็นคำขอฟีเจอร์ และบางส่วนเป็นบั๊กจริง
    • ผู้ดูแล insta ไม่ได้เจอปัญหานั้นโดยตรง แต่ในแง่ที่เป็น dependency ที่หยุดดูแลรักษา จึงถือเป็น หนี้ทางเทคนิค
  • สถานการณ์เปลี่ยนไปเมื่อ yaml-rust ถูกนำเข้าสู่การอภิปรายเรื่องการเพิ่มลงในฐานข้อมูล RUSTSEC
    • RUSTSEC ทำหน้าที่เป็น สถาบันจัดอันดับเครดิต ในอุปมาเชิงการเงิน
    • หลังจากขึ้นทะเบียน CI ของหลายโปรเจกต์ที่ใช้ yaml-rust โดยตรงหรือโดยอ้อมเริ่มล้มเหลวภายในไม่กี่นาที
    • เมื่อผู้ใช้ชี้ปัญหาการใช้ yaml-rust ต่อผู้ดูแล insta ก็เท่ากับเกิด margin call ตามอุปมาเชิงการเงิน

ทางเลือกและการรับมือจริง

  • การย้ายไปใช้ทางเลือกอื่นไม่ได้น่าดึงดูดนัก
    • ทางเลือกหนึ่งเป็น fork ของ yaml-rust มีผู้ดูแลเพียง 1 คน และเพิ่ม dependency อีก 3 ตัว
    • หนึ่งในนั้นได้รับอันดับ “B-” ไปแล้ว
    • ตัวเลือกอื่นในระบบนิเวศได้ตัดสินใจเปลี่ยนค่าเริ่มต้นก่อนที่จะถูกชี้ปัญหา
  • การ fork เองก็ไม่ใช่ทางแก้เชิงรากฐาน
    • ไลบรารีที่ fork มาเองยังมีข้อเรียกร้องด้านการดูแลรักษาแบบเดียวกันตามมา
    • หากไม่ตอบสนองต่อรายงานบั๊ก สุดท้ายก็จะถูกชี้ปัญหาเหมือน yaml-rust เดิม
    • ดังนั้น fork อาจซื้อเวลาได้ แต่ไม่ได้ทำให้ปัญหาหายไป
  • การรับมือจริงคือการ vendoring โดยรวมโค้ด yaml-rust เข้าไปใน insta
    • ตอนนี้ insta กลายเป็นรูปแบบที่รวมโค้ด insta กับ yaml-rust เข้าด้วยกัน
    • โครงสร้างนี้เหมือนกับการยกระดับหนี้ทางเทคนิคคุณภาพต่ำให้เป็น AAA
    • CDO ในชื่อเรื่องหมายถึงตราสารหนี้ที่มีสินทรัพย์ค้ำประกัน ซึ่งมีชื่อเสียในช่วงวิกฤตการเงินปี 2007
  • การประเมินสุดท้ายใกล้เคียงกับคำว่า “ไม่มีใครชนะ”
    • โค้ดที่มีปัญหาไม่ได้หายไป เพียงแค่ย้ายตำแหน่งเข้ามาอยู่ภายใน insta
    • แรงกดดันเมื่อมองเห็นเป็น dependency ภายนอกลดลง แต่ภาระการดูแลรักษาเองยังคงอยู่

1 ความคิดเห็น

 
GN⁺ 2024-03-27
ความคิดเห็นจาก Hacker News
  • พูดกันตรง ๆ คือ ผู้เขียน serde_yaml(https://lib.rs/crates/serde_yaml) ซึ่งเป็น YAML parser ที่ได้รับความนิยมมากที่สุด จู่ ๆ ก็ถอนตัวโดยไม่แจ้งล่วงหน้าหรือแต่งตั้งผู้ดูแลต่อ และทำเครื่องหมายว่า deprecated และ unmaintained
    ไม่เหมือน left-pad เสียทีเดียว แพ็กเกจยังทำงานอยู่ และ crates.io ก็ไม่อนุญาตให้ลบอยู่แล้ว แต่แพ็กเกจนี้ถูกใช้โดย crate อื่น ๆ 4,000 ตัว
    เครื่องมือตรวจสอบและอัปเดตอัตโนมัติจะเริ่มมองว่าการใช้ crate ที่ไม่มีผู้ดูแลเป็นปัญหา

    • ไม่ถูกต้องนัก ต้นฉบับบอกว่ามันพึ่งพา yaml-rust(https://github.com/chyh1990/yaml-rust) และโปรเจกต์นี้ต่างหากที่ตอนนี้ไม่มีผู้ดูแลแล้ว
      ขณะเดียวกัน serde_yaml ก็ถูกทำเครื่องหมายว่า unmaintained เพื่อกันไม่ให้ผู้คนแห่ย้ายไปทางนั้น
    • แม้จะไม่ใช่กรณีนี้ แต่ไลบรารีที่ไม่มี dependency บางครั้งอาจอยู่ในสถานะ ฟีเจอร์ครบถ้วนแล้ว จริง ๆ จนแทบไม่จำเป็นต้องเปลี่ยนแปลงอะไรนอกจากแพตช์ความปลอดภัย
      อยากให้เครื่องมือตรวจสอบกับนโยบายบริษัทฉลาดพอจะแยกแยะกรณีแบบนี้ได้ แทนที่จะเตือนว่า “ไม่มีผู้ดูแล” เพียงเพราะไม่มี commit ใหม่ ๆ
    • ผู้เขียนคนนั้นค่อนข้างเป็นคนที่ ผลิตผลงานเยอะ ใน ecosystem ไลบรารีของ Rust ไม่ใช่หรือ? เขาไม่ได้ทำแบบนี้กับไลบรารีอื่น ๆ
      เลยสงสัยว่ามีข้อมูลละเอียดกว่านี้ไหม
  • ตอนแรกผมไม่เข้าใจตัวย่อ CDO ที่โผล่มาโดยไม่มีคำอธิบาย แต่ในบทความใช้คำว่า collateralized หลายครั้ง น่าจะหมายถึง ตราสารหนี้ที่มีสินทรัพย์ค้ำประกัน (collateralized debt obligation)
    https://en.wikipedia.org/wiki/Collateralized_debt_obligation
    ตอนแรกนึกถึง chief data officer

    • อุปมาในที่นี้คือ CDO เป็น ผลิตภัณฑ์ทางการเงิน ที่สร้างขึ้นจากหนี้อื่น ๆ
      โดยเฉพาะในปี 2008 มันเป็นเหมือนสิทธิ์ถือครองบางส่วนในสินเชื่อที่อยู่อาศัยหลาย ๆ ก้อน และเมื่อสินเชื่อที่อยู่อาศัยด้อยคุณภาพผิดนัดชำระ CDO ก็พังไปด้วย [1]
      อย่างไรก็ตาม สิ่งที่ผู้เขียนคิดถึงน่าจะใกล้กับ ความเสี่ยงเชิงระบบ แบบ leftpad หรือเหตุขัดข้อง DNS แบบลูกโซ่มากกว่าการเปรียบเปรยบนฐานหนี้ เหตุผลใหญ่ที่ทำให้ปี 2008 วุ่นวายหนักก็เพราะปัญหาเชิงระบบ มากกว่าข้อเท็จจริงว่ามีการสร้างผลิตภัณฑ์จากหนี้เสียเอง [2]
      1. เกร็ดที่น่าสนใจคือ ก่อนปี 2008 ความต้องการผลิตภัณฑ์การเงินที่อิงสินเชื่อที่อยู่อาศัยโตไม่หยุด จนเริ่มมีการสร้าง CDO ที่ทำจาก CDO อีกที ถึงขั้นปล่อยสินเชื่อที่อยู่อาศัยให้คนไม่มีงานทำ แล้วเอามาห่อเป็นผลิตภัณฑ์เครดิตเรตติ้ง AAA ก็กลายเป็นสินค้าที่ทำกำไรและขายง่าย
      2. อีกเรื่องคืออัตราเลเวอเรจของ Lehman กับ Bear Stearns อยู่ที่ 30–40 เท่า ซึ่งบ้าคลั่งมาก
    • ใช่ ความหมายแฝงคือ หากสร้างแรงจูงใจให้เอาหนี้ทางเทคนิคที่ย่ำแย่ไปมัดรวมเป็นแพ็กเกจที่ดูน่าเชื่อถือ หรือก็คือ แพ็กเกจ AAA ecosystem ของ Rust อาจมุ่งหน้าเข้าสู่ฟองสบู่และล่มสลายในที่สุด
      ยังสื่อด้วยว่าสถาบันจัดอันดับที่ควรทำหน้าที่กำกับดูแลนั้นถูกเจาะไปแล้ว
    • ควรดู The Big Short ผมรู้จักว่า CDO คืออะไรจากเรื่องนั้น
    • เพิ่งตระหนักว่าตอนนี้มีคนรุ่นที่เด็กเกินกว่าจะได้อ่านพาดหัวข่าวยุคที่ CDO ทำเศรษฐกิจโลกพังแล้ว รู้สึกแก่เลย
    • ผมนึกถึง https://en.wikipedia.org/wiki/Collaboration_Data_Objects ;)
  • ผมไม่อยากเถียงว่านี่เป็น “ชัยชนะ” หรือไม่ เพราะขึ้นอยู่กับนิยามของคำว่า “ชัยชนะ” มากเกินไป แต่ข้อดีก็มีชัดเจน เส้นทางโค้ดที่มีช่องโหว่ซึ่งไม่ถูก execute และไม่สามารถเข้าถึงได้จากไลบรารีภายนอก ตอนนี้กลายเป็นเส้นทางโค้ดที่ปลอดภัยแล้ว
    แน่นอนว่ายังเป็นสภาพที่น่ากังวล แต่ก็ปลอดภัย
    การ vendoring แบบนี้ยังมีข้อดีอีกอย่างด้วย หากไลบรารีของคุณมี test coverage ที่แข็งแรง คุณก็สามารถรันเครื่องมือ code coverage กับไลบรารีที่เพิ่งนำเข้ามาได้
    การแก้ไลบรารีอาจทำได้ยาก แต่คุณก็อาจค่อย ๆ ลบส่วนที่โค้ดของตัวเองไม่ได้แตะต้องออกได้ค่อนข้างง่าย ขึ้นอยู่กับโครงสร้าง แต่ถ้าโค้ดที่มีช่องโหว่ถูกลบออกไปหมด นั่นก็เป็นประโยชน์ที่ชัดเจน และถ้าพบว่าจริง ๆ แล้วมีบางส่วนที่ใช้อยู่ ก็อาจเป็นประโยชน์ที่ชัดเจนยิ่งกว่า
    กล่าวคือ การ fork ไลบรารีเพื่อดูแลแบบสาธารณะเป็นความรับผิดชอบก้อนใหญ่ แต่การ vendor เฉพาะส่วนที่ต้องใช้เข้ามาแล้วปรับแต่งเองนั้นเป็นภาระที่เล็กกว่ามาก แม้จะไม่ได้ตัดกิ่งจริง ๆ แค่ทำให้การทำเช่นนั้นง่ายขึ้นก็ถือเป็นความก้าวหน้าแล้ว
    ข้อเสียก็มีชัดเจนเช่นกัน แต่ไม่ได้แย่ไปเสียทั้งหมด

    • ในทางปฏิบัติถือว่าเป็นผลลัพธ์ที่ดีมาก dependency ทุกตัวคือ ความเสี่ยงด้านความปลอดภัย และเหตุผลที่ไม่ควร vendor dependency ทุกตัวคือเราต้องคอยอัปเดต dependency ภายนอกให้ทันสมัยเพื่อหลีกเลี่ยงปัญหาความปลอดภัยที่รู้แล้ว
      แต่ถ้าไม่มีใครเฝ้าดู dependency ภายนอกนั้นอีกต่อไป เหตุผลนั้นก็หายไป และ dependency นั้นกลายเป็นภาระ
      การที่ dependency ถูกทำเครื่องหมายว่า abandoned และเริ่มถูกจับในรายงานความปลอดภัยคือพฤติกรรมที่ต้องการ เพราะทำให้ตัดสินใจได้อย่างมีข้อมูลว่าจะ vendor มันหรือไม่ กล่าวคือจะตัดความเสี่ยงที่ “ผู้ไม่หวังดีแอบใส่อะไรบางอย่างเข้าไป” ออกไป หรือจะเลือกทางอื่น
      อีกอย่างที่ดีคือระบบ build ของ Rust อนุญาตให้ทำสิ่งนี้ได้ง่าย
    • น่าชี้ให้เห็นว่า ที่ Google มีนโยบายบังคับให้ต้อง vendor dependency จาก third-party ทั้งหมด
      โดยปกติจะอนุญาตให้มีเวอร์ชันของ dependency นั้นเพียงเวอร์ชันเดียวทั่ว monorepo ขนาดใหญ่ทั้งหมดด้วย อาจเปลี่ยนไปแล้วหลังจากที่ผมออกมา
      และ dependency ใน third_party แต่ละตัวจะมีผู้รับผิดชอบหรือ OWNERS ที่กำหนดไว้
      สิ่งนี้ช่วยให้ทุกอย่างค่อนข้างเป็นระเบียบ
      แต่ระเบียบวินัยที่ถูกบังคับแบบนี้อาจเหมาะกับองค์กรอย่าง Google ที่มีเวลาและเงินเพียงพอ และไม่ได้ถูกผูกกับปรัชญา “เดินหน้าให้เร็วและทำของพัง” ส่วนจะเหมาะกับสตาร์ทอัพแค่ไหนนั้นไม่แน่ใจ
    • สงสัยว่ามีเครื่องมือที่ให้ maintainer ของไลบรารีคำนวณ transitive code coverage ของไลบรารีตัวเองได้ไหม เช่น test suite ของไลบรารีอื่นตัวใดบ้างที่ใช้งานมัน
      ในแง่หนึ่ง ไลบรารีอื่น ๆ เหล่านั้นเหมือน fuzz test แบบมีทิศทางที่ให้การเรียกใช้งานเกือบสุ่ม จึงอาจเป็นกลยุทธ์การทดสอบที่น่าสนใจ
  • เคยเห็นแพตเทิร์นเดียวกันในระบบนิเวศ JS npm เช่นกัน
    npm audit มักทำตัวเหมือนเด็กเลี้ยงแกะในเรื่องปัญหาความปลอดภัย และถ้าไลเซนส์อนุญาต การดึงโค้ดเข้ามาไว้ข้างในก็เป็นหนึ่งในวิธีที่เสถียรที่สุดที่จะไม่ถูกท่วมด้วยอิชชูปลอม ๆ จากผู้ใช้
    หลายครั้งผู้ใช้ไม่เข้าใจบริบท หรือไม่สนใจเพราะนโยบายของนายจ้างถูกกำหนดขึ้นในที่ที่ห่างไกลจากความเป็นจริง
    regex ที่ใช้ในบางส่วนของ codebase ของ dependency ทางอ้อมใน build pipeline ไม่ได้แปลว่าจะถูกนำไปใช้โจมตีแบบปฏิเสธการให้บริการได้จริง
    “อิชชู” ของ dependency ทางอ้อมที่อยู่ลึก ๆ อาจน่ารำคาญเป็นพิเศษในการหลีกเลี่ยง เพราะโดยโครงสร้างแล้ว มักพิสูจน์ทางเทคนิคได้ยากว่า “เราไม่มีทางเข้า code path นั้นเลย จึงไม่ได้รับผลจากข้อบกพร่องนี้” หรือ “กรณีเดียวที่จะเข้า path นั้นคืออินพุตที่เชื่อถือได้ในสภาพแวดล้อมออฟไลน์”

    • อิชชูของ development dependencies ในโลก JS นั้นปวดหัวจริง ๆ
      มีสถานการณ์ที่ปัญหาแบบนี้สำคัญอยู่จริง เช่น เครื่องมือ build ที่ถูกเจาะแล้วฉีดโค้ดอันตรายเข้าไปในไลบรารีที่กำลัง build
      แต่กรณีแบบนั้นพบได้น้อยมาก และถูกกลบอยู่ในคลื่นของ regex ที่อาจทำให้เกิดการปฏิเสธการให้บริการได้แต่จริง ๆ ไม่สำคัญ เพราะมันแค่ถูกเรียกตอน build เท่านั้น
      พอบวกกับข้อเท็จจริงที่ว่าเครื่องมือ build ทั่วไปมีต้นไม้ของ dependency ทางอ้อมราว ๆ ห้าหมื่นล้านตัว ก็ยิ่งกลายเป็นงานหนักมาก
      ผมคิดว่าเครื่องมือที่รายงานอิชชูเหล่านี้ควรแยกให้ออกระหว่าง “ถูก exploit ได้เมื่อ redistribute” กับ “ถูก exploit ได้เมื่อใช้ใน build pipeline”
    • แม้ตอนนี้จะยังไม่เข้า path ที่มีปัญหา นั้น แต่ในอนาคตเมื่อ dependency อัปเดต ก็อาจทำให้เข้าไปยัง path ที่มีปัญหา ได้
  • ในประโยค “ตอนนี้หนี้เทคนิคคุณภาพต่ำกลายเป็นระดับ AAA ไปเสียอย่างนั้น” คำว่า “ไปเสียอย่างนั้น” น่าจะหมายความว่า มันไม่สมเหตุสมผลที่โค้ดชุดเดิมได้อันดับหนี้ที่ดีกว่าเดิมเพียงเพราะถูก vendoring
    แต่นั่นเป็นการมองแค่มูลค่าของตัวโค้ดเอง และพลาดส่วนที่สำคัญที่สุดของ value proposition ทั้งหมด
    เมื่อ maintainer นำโค้ดเข้ามาไว้ข้างใน ตอนนี้โค้ดนั้นก็กลายเป็นของ maintainer คนนั้น ถ้า maintainer ที่ยัง active vendoring โค้ดจากโปรเจกต์ที่ตายไปแล้ว ก็จะมี คนที่ยัง active ซึ่งสามารถตอบสนองต่ออิชชู รีวิว pull request และแก้บั๊กได้ ทำให้มูลค่าของโค้ดนั้นสูงขึ้น
    ถ้าเปรียบอีกแบบ ก็เหมือนการส่งสัตว์เลี้ยงที่ถูกละเลยไปให้เจ้าของใหม่ ทำให้ได้รับการดูแลดีขึ้น สุขภาพดีขึ้น และมีชีวิตยืนยาวขึ้น มูลค่าจึงเพิ่มขึ้น

    • ใช้ได้เฉพาะกับคนที่ใช้ dependency นั้นทางอ้อมเท่านั้น ในกรณีนี้ จำนวนสายตาที่คอยมองหาบั๊กน่าจะน้อยมาก
      maintainer เองก็ต้องปรับตัวกับ codebase ขนาดใหญ่และไม่คุ้นเคย จึงจะเกิด กำแพงในการเข้าสู่โครงการ สำหรับการลงมือแก้หรือรีวิว
  • เป็นความคิดที่ออกนอกประเด็นเล็กน้อยและน่าจะถกเถียงกันได้ แต่ผมคิดว่าถ้า package manager แบบอิงซอร์สไม่รับรอง สิทธิ์ทางกฎหมาย ให้ registry เข้าควบคุมการดูแลแพ็กเกจสาธารณะโดยบังคับ ก็ยากที่จะหลีกเลี่ยงปัญหาร้าย ๆ ได้
    เช่น การถูกปล่อยทิ้ง การเปลี่ยนแปลงโดยเจตนาร้าย การลบโดยเจตนาร้าย และการแอบอ้าง
    ถ้าแพ็กเกจใดถูกมองว่าสำคัญพอต่อชุมชนที่ใหญ่กว่า ก็ควรมีวิธีดึงรายการแพ็กเกจใน registry ออกจากมือเจ้าของเดิมแล้วชี้ไปยัง fork แทน
    แน่นอนว่ามาตรการแบบนี้ย่อมมีดราม่ามากมายตามมา แต่สามารถปกป้องผู้ใช้ปลายน้ำได้อย่างจริงจัง

    • ผมว่าเรื่องนี้ไม่น่าเป็นปัญหาใหญ่ ความงามของโอเพนซอร์สอยู่ที่การ fork ได้
      ปัญหาจริงคือการดูแลโปรเจกต์โอเพนซอร์สต้องใช้เวลาและแรง และไม่ง่ายที่จะหาคนอื่นที่มีเวลาว่างมาทำ
    • package manager แบบอิงซอร์สที่ยึด ownership ของแพ็กเกจเมื่อ registry เห็นว่าจำเป็น ควรจะดึงดูด contribution ได้ยาก
      มันยังไม่น่าดึงดูดกว่ารูปแบบลิขสิทธิ์ที่ contribution ทั้งหมดกลายเป็นของกลุ่มใดกลุ่มหนึ่งโดยอัตโนมัติด้วยซ้ำ
      อาจพออ้างได้ว่า GitHub เป็นที่โฮสต์ซอฟต์แวร์เสรีและเชี่ยวชาญด้านการละเมิดลิขสิทธิ์ของซอฟต์แวร์นั้น แต่至少ตอนนี้ก็ยังไม่ได้พยายามยึด ownership ในนามของแพ็กเกจ
    • ถ้าเหตุผลคือความสำคัญในระดับชุมชน อย่างมากก็เป็นเรื่องที่ควรทำใน ระดับแพ็กเกจ ไม่ใช่ระดับ registry
      ในเมื่อพูดถึงชุมชน ก็ไม่ใช่ความสัมพันธ์แบบลูกค้า-ผู้จัดหา และแพ็กเกจส่วนใหญ่ก็สำคัญแค่พอที่จะถูกให้ใช้ฟรีเท่านั้น
      มันอาจกลายเป็นจำนวนเงินที่น่าอับอายอย่าง “ให้เดือนละ 10 ดอลลาร์ ช่วยดูแลแพ็กเกจ 100,000 ตัวให้เราหน่อย” ก็ได้
    • ปัญหาเหล่านี้ไม่ได้เป็นชนิดเดียวกันทั้งหมด แพ็กเกจที่ถูกแช่แข็งหมายความว่า downstream dependencies ต้องตัดสินใจ แต่ก็ยังมีทางเลือกมากมาย รวมถึง vendoring
      บนอินเทอร์เน็ตมีซอร์สโค้ดที่ไม่มีคนดูแลอยู่มากมาย และมันก็แค่ถูกเผยแพร่ไว้ครั้งหนึ่งตามสภาพเท่านั้น ไม่มีใครได้รับการรับประกันว่าจะมีอัปเดตสำหรับโค้ดฟรี
    • ทางเลือกอีกทางคือ ปัญหา Kik NPM ไม่ว่าทางไหนก็แย่
  • ถือว่าค่อนข้างโชคดีที่มีคน fork yaml-rust แล้วทำเป็น yaml-rust2(https://github.com/Ethiraric/yaml-rust2/blob/master/document...) ไว้แล้ว
    น่าดีใจด้วยที่ fork นั้นผ่าน YAML test suite ทั้งหมด และยังเร็วกว่าใน benchmark ด้วย การ migrate ก็ดูง่าย
    สุดท้ายปัญหาก็ยังอยู่ เราพึ่งพางานของคนอื่นที่ตอนนี้ยินดีมอบแรงงานให้ฟรี แต่สิ่งนั้นอาจไม่ได้ดำเนินต่อไปตลอดกาล
    ผมไม่รู้ว่ามีทางเลี่ยงอื่นไหม นอกจากตอบแทนเวลาและความพยายามของพวกเขา แล้วหวังว่าพวกเขาจะทำงานดี ๆ ต่อไป

    • yaml-rust เดิมทีเป็น implementation แบบ Rust ล้วน และ tagline ก็เขียนไว้ตามตัวอักษรแบบนั้น
      “A pure rust YAML implementation.”
      ในทางกลับกัน serde_yaml ถือว่าเป็น Rust ล้วนได้ยากกว่า เพราะพึ่งพา unsafe-libyaml ซึ่งแปลง libyaml มาด้วย c2rust
    • โปรเจกต์ที่มี bus factor 1 มีความเสี่ยงโดยธรรมชาติ
      ถ้ามองในกรอบเวลาที่ยาวพอ ความน่าจะเป็นที่ maintainer โอเพนซอร์สจะเลิกทำโปรเจกต์คือ 1
      วิธีเดียวที่จะหลีกเลี่ยงสิ่งนี้ได้คือทำให้โปรเจกต์ที่มีผู้ดูแลคนเดียวกลายเป็นเรื่องต้องห้าม
    • วิธีแก้พื้นฐานของผมสำหรับปัญหานี้คือหลีกเลี่ยง third-party dependencies ให้มากที่สุด
      สำหรับโปรเจกต์ Rust อาจไม่ใช่ตัวเลือก เพราะคนที่ทำ standard library ของ Rust ต้องการให้ standard library คงความบางเบาไว้
      แต่เมื่อใช้ภาษาอื่นที่มี standard library ซึ่งมีฟังก์ชันเพียงพอ นี่เป็นตัวเลือกที่เป็นไปได้แน่นอน
      เพราะผมตั้งใจใช้ภาษาที่มีสิ่งจำเป็น built-in อยู่แล้ว เลยแทบไม่ใช้ไลบรารีภายนอกนอกจาก database driver
  • สถานการณ์ทั้งหมดนี้ดูค่อนข้างตลก ถ้าโค้ดมันทำงานได้ และเป็นแบบนั้นมาหลายปีแล้ว ก็ไม่รู้ว่าการที่มันไม่มีคนดูแลจะเป็นปัญหาตรงไหน
    ถ้าไม่จำเป็นต้องแก้ไข และรู้ข้อจำกัดกับความสามารถของมันอยู่แล้ว ก็โอเค
    โค้ดไม่ได้เสียเองไปตามกาลเวลา ผมเคยยืมหรือผสานโค้ดเมื่อหลายสิบปีก่อนมาใช้ได้ดีหลายครั้ง
    ส่วนตัวแล้วคงจะมองข้ามคำบ่นทั้งหมดเกี่ยวกับไลบรารีนั้นไปเลย

    • คำตอบที่ชัดเจนคือ ในหลายแง่มุมมันไม่ได้ “ทำงาน” จริง ๆ
      มีบั๊กสะสมอยู่มากมายแล้ว และแม้จะมีแพตช์แก้ไขอยู่ ก็จะไม่มีวันถูกนำไปแพตช์ ดูได้ที่ https://github.com/chyh1990/yaml-rust/issues และ /pulls
    • การที่บอกว่ายืมหรือผสานโค้ดเมื่อหลายสิบปีก่อนมาใช้ นั่นไม่ใช่สิ่งที่ผู้เขียนทำโดย vendor ไลบรารีเข้าไปในโปรเจกต์ของตัวเองหรือ?
      ก็เหมือนกับรับภาระดูแลชิ้นส่วนโค้ดที่ตัวเองใช้อยู่เอง
      บางครั้งก็อาจไม่ดี เพราะอาจกลายเป็นการเขียนโค้ดแบบคัดลอก-วาง หรือทำงานซ้ำซ้อน
      แต่ถ้าคอมโพเนนต์จากบุคคลที่สามไม่มีคนดูแลโดยสิ้นเชิง ก็ถือว่าเข้าใจได้อยู่
  • ใช่แล้ว dependency ก็ vendor ได้ dependency ที่ใกล้เคียงกับ “เกือบเสร็จสมบูรณ์” และการพัฒนากับการดูแลชะลอตัวลง โดยทั่วไปเราก็ทำแบบนั้นกันมาตลอด 20 ปี
    เพียงแต่ผมไม่เคยทำงานกับภาษาที่เป็นแบบ “batteries are not included”

  • จะมีวิธีทำอะไรอย่าง cargo vendor --aggressive เพื่อ prune โค้ดที่ตายแล้ว ทั้งหมดใน dependency โดยอิงจาก crate ของผมได้ไหม?
    สงสัยว่าจะช่วยให้ปัญหาเรื่อง “รีวิว dependency” จัดการได้ง่ายขึ้นหรือเปล่า
    แม้จะออกนอกประเด็นหลักของบทความ แต่ก็เกี่ยวข้องกันในแง่ที่ท้ายที่สุดแล้ว การเลือก dependency และความรับผิดชอบทั้งหมดที่ตามมาก็เป็นของเรา
    ดูเหมือนว่ายังมีที่ว่างสำหรับเครื่องมือที่จะช่วยให้เรารับผิดชอบต่อสิ่งที่ถูกคอมไพล์เข้าไปใน crate จริง ๆ ได้มากขึ้น

    • แล้วต้องคัดลอก รายงานบั๊ก ทั้งหมดของไลบรารีเข้ามาในระบบติดตามบั๊กของตัวเองด้วยไหม?
      ถ้าไม่ทำแบบนั้น ก็ไม่เห็นว่ามันดีขึ้นตรงไหน