7 คะแนน โดย GN⁺ 2023-07-29 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • การเลือกใช้ การยกเลิก RPC เปลี่ยนจากการเรียก context.allowCancellation() ไปเป็น annotation allowCancellation ใน schema
  • ผู้ใช้ที่ไม่ได้ใช้ context.allowCancellation() ไม่จำเป็นต้องแก้ไขเมื่ออัปเกรดเป็น 1.0 และการยกเลิกจะยังคงไม่ถูกอนุญาตเป็นค่าเริ่มต้น
  • 1.0 เป็นรีลีสลักษณะ การสนับสนุนระยะยาว (LTS) โดยมีแผนจะ backport bugfix ไปยัง branch 1.0 ในระยะยาว
  • มีการปรับปรุงประสิทธิภาพของ Cap’n Proto RPC โดยลดการจัดสรรหน่วยความจำในตัว implementation ของ RPC และ KJ I/O framework, ตัดบาง RPC protocol message ออก, และลด syscall ผ่านการปรับปรุงการ buffering ของ message ขนาดเล็ก
  • KJ ใช้ kqueue() สำหรับการประมวลผล asynchronous I/O บน MacOS และตระกูล BSD โดยเปลี่ยนจากวิธีเดิมที่อิง poll() ซึ่งช้ากว่า
  • การ implementation ของ KJ HTTP client และ server รองรับเมธอด CONNECT
  • มีการเพิ่ม capnp::RevocableServer เพื่อช่วยหลีกเลี่ยงบั๊ก use-after-free เมื่อต้อง export object ที่ wrapper ไม่ได้ควบคุม lifetime ออกไปเป็น RPC wrapper
  • การพัฒนา 2.0 จะดำเนินต่อบน branch v2 ใหม่ และมีแผนให้ branch master กลายเป็น branch 1.0 LTS เพื่อไม่ให้โปรเจ็กต์เดิมหยุดทำงานเพราะการเปลี่ยนแปลง
  • แผนของ 2.0 ไม่ใช่การเปลี่ยนแปลงแบบไม่รองรับย้อนหลังใน serialization format หรือ RPC protocol แต่เน้นการเปลี่ยนแปลงที่ C++ API และ KJ เป็นหลัก ดังนั้นแอปพลิเคชันที่เขียนด้วยภาษาอื่นจะไม่ได้รับผลกระทบ
  • แผนของ 2.0 รวมถึงการต้องใช้คอมไพเลอร์ C++20 หรือ C++23, การใช้ C++20 coroutine, การยกเลิกการรองรับ exception disabled และโหมด no-RTTI, รวมถึงการเปลี่ยนแปลง API ของ kj::Maybe และ kj::AsyncOutputStream

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

 
alstjr7375 2023-07-29

โอ้..ในที่สุดก็มาจนได้

 
GN⁺ 2023-07-29
ความคิดเห็นจาก Hacker News
  • ขอแจ้งข่าวที่น่าเศร้าอย่างยิ่งต่อชุมชน Cap'n Proto และ Sandstorm: Ian Denhardt (zenhack บน HN) ซึ่งเป็นผู้มีส่วนร่วมหลักของ implementation ภาษา Go ได้จากไปอย่างกะทันหันเมื่อไม่กี่สัปดาห์ก่อน และตลอด 3 ปีที่ผ่านมาเราได้ร่วมงานกันมากจนกลายเป็นเพื่อนกัน จึงรู้สึกสูญเสียอย่างใหญ่หลวง
    ในฐานะที่แทบจะเป็นหัวหน้าโปรเจกต์ ตอนนี้ผมต้องเติมเต็มช่องว่างขนาดใหญ่ที่ Ian ทิ้งไว้ ดังนั้นหากคุณสามารถช่วยมีส่วนร่วมกับโปรเจกต์ได้ เราต้องการความช่วยเหลืออย่างมาก หากคุณเป็นผู้มีส่วนร่วมหรือเมนเทนเนอร์ของ implementation อื่น ๆ เช่น C++, Rust ฯลฯ ผมอยากให้ติดต่อมาจริง ๆ การสานต่องานของ Ian ต้องอาศัยการทำงานร่วมกับคนที่ฉลาดมาก ๆ
    RIP Ian ผมได้เรียนรู้อะไรมากมายจริง ๆ จากการทำงานร่วมกับคุณ ช่องทางติดต่อ: https://github.com/lthibault, https://matrix.to/#/#go-capnp:matrix.org, Telegram @lthibault, gmail louist87

    • ผมเคยเจอคนที่จากไปอย่างกะทันหันมาหลายครั้งแล้ว และมันเป็นเรื่องที่ทำให้จิตใจพังทลายจริง ๆ ทุกครั้งที่เกิดเรื่องแบบนั้น มันทำให้นึกถึงว่า ชีวิตเปราะบางแค่ไหน และทุกอย่างสามารถเปลี่ยนแปลงได้รวดเร็วเพียงใด
      ผมไม่ได้เมินอนาคต แต่ก็พยายามสนุกกับสิ่งเล็ก ๆ ในชีวิตให้มากขึ้น Ian ได้ทิ้งมรดกอันน่าทึ่งที่ส่งผลถึงผู้คนมากมายไว้เบื้องหลัง RIP Ian
    • ผมไม่เคยทราบข่าวนี้มาก่อน จึงรู้สึกช็อกมาก ผมชอบ บล็อก ของ Ian มาก น่าเสียใจจริง ๆ
    • ดูเหมือนว่า @zenhack ยังเป็นผู้ดูแล Haskell bindings ด้วย
    • แม้จะไม่รู้จักเป็นการส่วนตัว แต่ผมชื่นชมงานของเขาอย่างมากกับ Tempest ซึ่งเป็น fork ล่าสุดที่พยายามชุบชีวิต Sandstorm ขอบคุณที่แจ้งข่าวนี้
    • เป็นข่าวที่เศร้าจริง ๆ Ian เป็นแรงบันดาลใจให้ผู้คนมากมาย และจะเป็นการสูญเสียครั้งใหญ่ของทั้งชุมชน
  • น่าแปลกใจที่นอกจาก Cap'n Proto แล้ว มีโปรโตคอลที่มี promise pipelining น้อยมาก ตัวอย่างอื่นที่นึกออกมีแค่ 9p แต่ 9p ไม่ใช่โปรโตคอลเอนกประสงค์
    https://capnproto.org/news/2013-12-13-promise-pipelining-cap...

    • ถึงจะเป็นฟีเจอร์ที่เจ๋ง แต่ดูเหมือนจะทำให้ปรับแต่งแบ็กเอนด์ให้เหมาะสมได้ยากกว่าแนวทางที่รวมคำสั่งค้นหาอย่างชัดเจน เช่น custom RPC call ที่จบด้วย SQL query เดียวอาจดีกว่า RPC call แยกหลายครั้งที่ถูก pipeline ไว้
      ถึงอย่างนั้นก็น่าจะเป็นฟีเจอร์ที่ควรถูกใช้แพร่หลายกว่านี้
    • Pipelining เป็นไอเดียที่ไม่ดี เพราะมันทำให้ object instance ถูก materialize จึงทำให้การ implement ให้แข็งแรงทำได้ยากขึ้นมาก มันไม่ใช่การเรียกแบบไร้สถานะอีกต่อไป แต่กลายเป็นโครงสร้างที่รันฟังก์ชันบน object instance เฉพาะตัว
      เช่น ถ้าไคลเอนต์ Joe เรียก Service A แล้วส่งผลลัพธ์ที่เป็น promise นั้นต่อไปให้ Service B, Service B ก็ต้องทำ remote call ไปยัง Service A เพื่อรับผลลัพธ์ของ promise นั้น
      ตอนนั้นขอบเขตความปลอดภัยจะซับซ้อนขึ้นทันที โมเดลการมอบอำนาจจะจัดการอย่างไรก็เป็นปัญหา แต่ที่ร้ายกว่านั้นคือ backpressure จะหายไป ถ้าไคลเอนต์ Joe สร้างคำเรียกหลายพันครั้งไปยัง Service A แล้วส่งผลลัพธ์ที่ยังไม่ถูก materialize ต่อไปยัง Service B, Service A อาจถูกถาโถมเหมือน DDoS จน Service B timeout ได้
    • ไม่เคยรู้ว่า 9p มี promise pipelining พูดให้แม่นกว่านั้นคือไคลเอนต์สามารถเลือก file descriptor ได้เอง จึงสามารถส่งคำขออ่านไฟล์นั้นได้ทันทีหลังเปิดไฟล์ และถ้าการเปิดล้มเหลว การอ่านก็จะล้มเหลวด้วย EBADF เป็นโครงสร้างที่เจ๋งดี
      อย่างไรก็ตาม promise pipelining ต้องการการรองรับจากฝั่งไคลเอนต์ด้วย ถ้าผู้ใช้ส่ง walk หลายรายการออกไป ก็สงสัยว่ามีไคลเอนต์ 9p ที่ส่งทั้งหมดโดยไม่รอ response ของ walk แรกหรือไม่
      อีกอย่าง 9p ให้ promise pipelining เฉพาะกับ file descriptor เท่านั้น แค่นี้ก็ทำอะไรได้มากแล้ว แต่ถ้าอยากอ่านไฟล์ทั้งหมดในไดเรกทอรี ก็ควรจะสามารถส่ง read แล้วใช้ผลลัพธ์ของ read นั้นไป walk ต่อได้ แต่ดูเหมือน 9p จะไม่รองรับสิ่งนี้ ในไลบรารีโปรโตคอล remote system call ของผมชื่อ rsyscall รองรับสิ่งนี้จริง ๆ
    • บรรพบุรุษทางแนวคิดของ Cap'n Proto มี CapTP/VatTP หรือที่รู้จักกันว่า Pluribus ซึ่งพัฒนาร่วมกับภาษา E ของ Mark Miller และยังมีอุปกรณ์ที่เล่นคำชื่อ “unum” ด้วย หากอยากดูสายตระกูลที่ลึกกว่านี้ให้ดูวิทยานิพนธ์ของเขา ซึ่งในนั้นยังพูดถึง promise pipelining ของ Barbara Liskov และไอเดียที่เกี่ยวข้องใน Argus ซึ่งเป็นส่วนขยายของ CLU ด้วย
      ถ้าจำไม่ผิด Mark Miller ภายหลังก็เป็นคนเขียนข้อเสนอ promise ของ JavaScript ด้วย แต่ส่วนขยาย RPC ไม่ได้เกิดขึ้นจริง และเราได้ async/await มาแทน ซึ่งดูไม่ค่อยเข้ากับ pipelining นัก
      Spritely Goblins และ OCapN ซึ่งเป็นความพยายามที่ใหม่กว่าในการสร้างระบบสิทธิ์แบบกระจายตามแนวทางของ E ก็ผลักดัน pipelining เช่นกัน ดังนั้นถ้าอยู่ใน cap-talk ก็น่าจะได้ยินเกี่ยวกับโปรโตคอลที่คล้ายกันอีกสองสามตัว แม้ use case จริงจะมีน้อยก็ตาม
      อย่างไรก็ตาม แม้จะเป็นฟีเจอร์ที่เจ๋ง แต่ promise pipelining ดูเหมือนต้องเขียนโปรแกรมด้วย promise แบบ explicit จริง ๆ และเราก็รู้กันดีอยู่แล้วว่าสิ่งนั้นอาจยุ่งยากได้แค่ไหน
      ในอีกด้านหนึ่ง คือฝั่ง event loop และ “active object” แบบ cooperative concurrency มีไอเดียที่น่าสนใจและคนรู้น้อยกว่าอย่าง causality IDs ของ DCOM/COM+ เป็นกลไกควบคุม reentrancy ดูเอกสาร Microsoft เรื่อง CoGetCurrentLogicalThreadId และการอภิปราย CALLTYPE_TOPLEVEL_CALLPENDING ใน Effective COM ได้ ภายหลังเหมือนว่า Microsoft พยายามขายมันเป็นฟีเจอร์ใหม่ใน ASTA ของ Win8/UWP
      [1] http://erights.org/elib/distrib/captp/index.html
      [2] http://erights.org/talks/thesis/index.html
      [3] https://spritely.institute/goblins/
      [4] https://github.com/ocapn/ocapn
      [5] https://groups.google.com/g/captalk/
      [6] https://learn.microsoft.com/openspecs/windows_protocols/ms-d...
      [7] https://learn.microsoft.com/windows/win32/api/combaseapi/nf-...
      [8] https://archive.org/details/effectivecom50wa00boxd/page/150
      [9] https://devblogs.microsoft.com/oldnewthing/20210224-00/?p=10...
    • ไม่แน่ใจว่า promise pipelining ของ Cap'n Proto ทำงานอย่างไรแน่ แต่กังวลกับกรณีที่ต้องการอ่านไดเรกทอรีแล้ว stat ทุก entry ในนั้น หรือเมื่ออยากส่งต่อแค่หนึ่งในสองค่าจาก response ไปยังการเรียกถัดไป
      กรณีหลังน่าจะทำได้สักทาง แต่กรณีแรกขึ้นอยู่กับจำนวนค่าต่าง ๆ ในรายการผลลัพธ์
  • ยินดีด้วยกับการเปิดตัว คงน่าตื่นเต้นมากเพราะใช้เวลาถึง 10 ปี สงสัยว่าต่อไปจะมีงานเพิ่มเติมกับ implementation สำหรับภาษาอื่น ๆ อีกไหม
    ผมชอบไอเดียของฟอร์แมตนี้มาก แต่ภาษาหลัก ๆ ในสแต็กของเรายังไม่ได้รับการซัพพอร์ตพอที่จะอยากใช้ในผลิตภัณฑ์

    • จุดนี้เป็น จุดอ่อนที่ใหญ่ที่สุดของ Cap'n Proto จริง ๆ สิ่งเดียวที่ผมดูแลอย่างจริงจังคือ implementation ภาษา C++ ส่วน implementation อื่น ๆ มาจากผู้มีส่วนร่วมหลายคน ระดับความสมบูรณ์และคุณภาพจึงแตกต่างกันไป
      น่าเสียดายที่ตรงนี้ผมสัญญาอะไรใหม่ ๆ ได้ยาก งานของ Cap'n Proto ขับเคลื่อนโดยความต้องการของโปรเจกต์หลักของผมคือรันไทม์ Cloudflare Workers ซึ่งส่วนใหญ่เป็น C++ และยังมีการโต้ตอบกับบริการ Go และ Rust ด้วย ซึ่ง implementation เหล่านั้นก็ดูเหมือนจะทำหน้าที่ของมันได้ในบริบทนั้น
      กล่าวอีกอย่าง Cap'n Proto เป็นโปรเจกต์โอเพนซอร์ส และผมหวังว่ามันจะเป็นประโยชน์กับผู้คน แต่ไม่ใช่ผลิตภัณฑ์ที่ผมพยายามขาย ดังนั้นจึงไม่ได้โฟกัสเป็นพิเศษกับการทำให้ทุกคนรับไปใช้ เช่นเคย ยินดีรับ contribution เสมอ
      กรณีหนึ่งที่อาจมีการเปลี่ยนแปลงครั้งใหญ่ได้ คือถ้า Cloudflare ตัดสินใจทำให้ Cap'n Proto เป็นฟีเจอร์สาธารณะของแพลตฟอร์ม Workers ตอนนั้นจะเกิดความจำเป็นโดยตรงที่จะต้องขัดเกลาให้ดีจริง ๆ ในหลายภาษา เรื่องนี้มีการคุยกันเป็นครั้งคราว แต่ตอนนี้ยังไม่มีแผน
    • เคยมีคนที่อยากเขียน เลเยอร์ RPC เอง แทนที่จะเป็น wrapper ครอบ implementation ภาษา C++ แต่โค้ดที่ต้องเขียนใหม่มีเยอะมากเมื่อเทียบกับประโยชน์โดยตรง
      ถ้าอยากลองก็ลองได้ คนอื่น ๆ น่าจะให้ความร่วมมือพอสมควร แต่อยากให้รู้ไว้ว่างานมันเยอะมากจริง ๆ
  • เพิ่มบริบทอีกนิด Kenton เคยดูแล ระบบ proto ภายในของ Google มาหลายปี แล้วหลังจากออกมาก็สร้างเวอร์ชันโอเพนซอร์สของตัวเอง

    • น่าจะเป็นเขานั่นแหละที่เป็นคนเผยแพร่ protobuf เป็นโอเพนซอร์ส
  • ถ้ามีพนักงาน Cloudflare คนไหนมีส่วนในการเลือก Cap'n Proto แทนอย่างอื่นอย่าง protobuf ก็อยากรู้ว่ามีข้อพิจารณาอะไรบ้าง อยากรู้ว่าเหตุผลนั้นสำคัญกับผมด้วยไหม หรือเป็นเรื่องที่ไม่ต้องสนใจถ้าไม่ได้จัดการสเกลมหาศาล

    • มีบล็อกโพสต์เกี่ยวกับการที่ Cloudflare ใช้ Cap'n Proto ในปี 2014 ซึ่งเป็น 3 ปีก่อนผมเข้าร่วม: https://blog.cloudflare.com/introducing-lua-capnproto-better...
      แม้ตอนนี้ data pipeline ของ Cloudflare หรือระบบที่สร้าง log และ analytics ที่ edge ก็ยังอิงกับ การ serialize ด้วย Cap'n Proto เป็นส่วนใหญ่ ผมไม่ได้มีส่วนร่วมกับโปรเจกต์นั้นเป็นการส่วนตัวมากนัก
      ส่วน Cloudflare Workers นั้น ผมเป็นคนเริ่มโปรเจกต์ ก็เลยใช้ของของผมเอง คงไม่ใช่คำอธิบายที่คุณอยากได้เท่าไร
      แต่ถึงอย่างนั้น ผมเห็นว่าโปรโตคอล RPC ของ Cap'n Proto มีความสามารถในการแสดงออกสูงกว่าทางเลือกอื่นมาก จึงช่วยได้มากกับการทำ implementation ของ sandboxing ใน Workers Runtime และฟีเจอร์ระบบกระจายอย่าง Durable Objects https://blog.cloudflare.com/introducing-workers-durable-obje...
    • ผมไม่ได้ทำงานที่ Cloudflare แต่ติดตามงานของพวกเขา และบางครั้งก็ทำโปรเจกต์ที่อ่อนไหวต่อ performance เดาว่า Cap'n Proto, flatbuffers, SBE ฯลฯ น่าจะถูกมองเป็นคนละหมวดกับฟอร์แมตข้อมูลอื่นอย่าง Avro หรือ protobuf
      ถ้าคุณเลือกข้อมูลในรูปแบบที่ใกล้เคียง record ไม่ใช่แบบ column-oriented อย่าง Parquet และต้องการฟอร์แมตที่แทบไม่มีเวลาพาร์สล่วงหน้าเลย ตัวเลือกก็จะเหลือค่อนข้างน้อย อาจมี marshalling ตอนอ่านถ้ามีการเปลี่ยนค่าฟิลด์
      https://capnproto.org/news/2014-06-17-capnproto-flatbuffers-... พูดถึง trade-off นี้
      เดิมที Cap'n Proto ถูกสร้างขึ้นสำหรับ https://sandstorm.io/ และงานที่ Kenton ทำหลังจากถูก Cloudflare จ้างก็คงนำไปสู่ Cloudflare Workers ในที่สุด
      ข้อพิจารณาอีกอย่าง: https://github.com/google/flatbuffers/issues/2#issuecomment-...
    • สรุปสถานการณ์ตอนที่ผมเข้าร่วมมาได้ราว ๆ หนึ่งปีกว่า ๆ คือ Cloudflare กำลังสร้างวิธีส่ง log จาก edge ไปยังจุดศูนย์กลาง เพื่อทำ analytics ให้ลูกค้าและให้บริการ log สำหรับลูกค้า enterprise
      เท่าที่ผมเข้าใจ Albert Strasheim วิศวกรหลักที่สร้างทั้งหมดนั้น ได้ benchmark ตัวเลือก serialization หลัก ๆ และได้ผลว่า Cap'n Proto เร็วกว่า protobuf พอสมควร
      มี implementation ภาษา C++ ที่ยอดเยี่ยม และใช้งานกับ nginx ได้ เท่าที่จำได้มี Lua เข้ามาเกี่ยวข้องเล็กน้อยด้วย implementation ภาษา Go ที่ฝั่งผู้บริโภคใช้อยู่ยังมีส่วนที่หยาบอยู่บ้าง แต่ส่วนสำคัญที่จำเป็น คนในทีมก็แก้ได้
      Cloudflare ให้ความสำคัญกับประสิทธิภาพด้านต้นทุนเครื่องมาโดยตลอด ดังนั้นเมื่อพิจารณาความต้องการด้าน performance ตอนนั้น นี่จึงเป็นตัวเลือกที่เป็นธรรมชาติ ระหว่างที่ผมอยู่ทีม data Cap'n Proto ค่อนข้างทำงานด้วยง่าย และวิธีแชร์นิยาม proto จากคลัง schema กลางก็ทำงานได้ดี
    • เป็นไปได้สูงว่าการเลือกทำได้ง่าย เพราะ lead developer ของ Cloudflare Workers คือ ผู้สร้าง Cap'n Proto
  • ผมตั้งตารอที่ Cap'n Proto เข้าร่วมงาน มาตรฐาน OCapN สงสัยว่านี่จะเป็นส่วนหนึ่งของงาน Cap'n Proto 2.0 หรือไม่
    https://github.com/ocapn/ocapn

    • น่าเสียดายที่ Ian “zenhack” Denhardt ผู้ผลักดันการมีส่วนร่วมนี้ เพิ่งจากไปอย่างกะทันหันเมื่อไม่นานมานี้
      ผมชอบ OCapN แต่ด้วยงานที่รับผิดชอบอยู่มากมายตอนนี้ ผมไม่รู้ว่าจะทุ่มเวลาให้เป็นการส่วนตัวได้มากแค่ไหน อยากจะมีข่าวที่ดีกว่านี้ให้บอก แต่นี่เป็นการสูญเสียที่น่าเศร้าสำหรับพวกเราทุกคน
  • แม้ผมจะไม่เคยใช้ Cap'n Proto แต่ก็ขอบคุณคำตอบ FAQ ที่มีประโยชน์มากของ kentonv [1] ซึ่งอธิบายว่าเหตุใด ฟิลด์บังคับ ในโปรโตคอลจึงเป็นปัญหา
    ผมมักลิงก์ไปที่คำตอบนี้บ่อย ๆ ทุกครั้งที่มีคนถามว่าทำไม protobuf 3 ถึงไม่มีฟิลด์ required
    [1] https://capnproto.org/faq.html#how-do-i-make-a-field-require...

    • เป็นมุมมองที่มีคุณค่าจริง ๆ ผมเองเมื่อก่อนก็เข้าใจยากว่าทำไมถึงเป็นเช่นนั้น ประเด็นสำคัญคือการมอง protobuf และ Cap'n Proto ว่าเป็นรูปแบบการซีเรียลไลซ์ที่ต้องทำงานข้าม ขอบเขต API กับสคีมาคนละเวอร์ชัน พร้อมความเข้ากันได้ทั้งย้อนหลังและไปข้างหน้า ไม่ใช่โครงสร้างข้อมูลในหน่วยความจำที่แทนโลกตามที่โปรเซสเดียวเวอร์ชันเดียวมองเห็น
      ดังนั้นมนตราที่พูดซ้ำกันบ่อย ๆ ว่า “ทำให้สถานะที่ผิดกฎหมายไม่สามารถแทนค่าได้” จึงใช้กับกรณีนี้ไม่ได้
    • Typical มี ฟิลด์แบบไม่สมมาตร เพื่อช่วยเรื่องวิวัฒนาการของชนิดข้อมูล:
      https://github.com/stepchowfun/typical#asymmetric-fields-can...
      เพื่อให้เพิ่มและลบฟิลด์บังคับได้อย่างปลอดภัย Typical จึงมี asymmetric ซึ่งเป็นสถานะกึ่งกลางระหว่างฟิลด์เลือกได้กับฟิลด์บังคับ ฟิลด์ asymmetric ใน struct จะถือว่าเป็นฟิลด์บังคับสำหรับฝั่งเขียน และเป็นฟิลด์เลือกได้สำหรับฝั่งอ่าน ต่างจากฟิลด์เลือกได้ ฟิลด์ asymmetric สามารถเลื่อนเป็นฟิลด์บังคับได้อย่างปลอดภัย หรือย้อนกลับในทางตรงกันข้ามได้
    • ถ้าขยายตรรกะนี้ออกไป ก็อาจสรุปได้ว่าแทบควรเลิกใช้ static type ทั้งหมดด้วยซ้ำ พูดตรง ๆ ก็ไม่ใช่ว่าผิดไปเสียทีเดียว และนี่ก็เป็นเหตุผลที่ Alan Kay นิยามแนวคิดเชิงวัตถุด้วย dynamic type และ late binding แต่เรากลับเดินไปในทิศทางตรงข้าม แล้วก็ต้องเรียนบทเรียนเดิมซ้ำแล้วซ้ำอีก
    • ใน FAQ [1] ระบุว่า “คำตอบที่ถูกต้องคือให้แอปพลิเคชันตรวจสอบในโค้ดระดับแอปพลิเคชันตามความจำเป็น”
      ผมอยากให้มีพารามิเตอร์ที่เปิดปิด การตรวจสอบข้อความบังคับ ได้ แทนที่จะต้องพึ่งโค้ดแอปพลิเคชัน ภายในแอปหรือบน message bus อาจปิดได้ แต่โดยทั่วไปถ้าเปิดไว้ก็ช่วยนักพัฒนาได้มาก
      [1] https://capnproto.org/faq.html#how-do-i-make-a-field-require...
    • ยังมีกับดักในทำนองเดียวกันอีกอย่าง คือปัญหาที่มีการ deserialize สิ่งที่ไม่จำเป็นมาด้วย เหมือนที่ได้รับจาก client ที่ generated มา
      สิ่งที่ผมชอบมากใน interface ของ Go คือผมสามารถทำ type เฉพาะส่วนที่ใช้แบบ remote และข้ามส่วนที่เหลือได้ บริการล่มเพราะการเปลี่ยน contract ที่บริการนั้นไม่ได้ใช้ด้วยซ้ำไม่ใช่เรื่องสนุก และยังหาต้นเหตุได้ยากด้วย
  • เป็นผลงานที่ยอดเยี่ยม พูดตรง ๆ ผมคงไม่แนะนำ Cap'n Proto เพราะ C++ API ใช้งานกระอักกระอ่วนมาก
    ประโยชน์ของการพาร์สแบบไม่ต้องคัดลอกก็น้อยกว่าที่คาด ด้วยความที่ใช้งานไม่คล่องตัว โอกาสที่คุณจะอยากถือข้อมูลไว้ในโครงสร้างข้อมูลของ Cap'n Proto ต่อไปจึงต่ำ และ 99% สุดท้ายก็ต้องคัดลอกไปยังโครงสร้างข้อมูลของตัวเองอยู่ดี
    โลกส่วนใหญ่ลงตัวกับ Protobuf สำหรับการทำไบนารีลักษณะนี้แล้ว จึงมีแรงเสียดทานกับระบบอื่นมากกว่า
    ผมเคยใช้แค่เพื่อการซีเรียลไลซ์ ฝั่ง RPC อาจน่าสนใจกว่าก็ได้
    ผมคงดีใจมากถ้า Thrift ประสบความสำเร็จแทน Protobuf/gRPC มันออกแบบได้ดีกว่าและยืดหยุ่นกว่าสิ่งใด ๆ ที่ผมเคยเห็นมาก ทั้งก่อนหรือหลังจากนั้น ดูเหมือนว่ามันจะหายไปหลัก ๆ เพราะเอกสารแย่มาก และคงเพราะไม่มีชื่อใหญ่ ๆ หนุนหลังด้วย

    • เห็นด้วยว่า API ที่จำเป็นสำหรับ zero-copy จะออกมากระอักกระอ่วนอยู่บ้าง โดยเฉพาะฝั่งเขียน ส่วนฝั่งอ่านไม่ได้ต่างกันมากนัก อีกด้านหนึ่ง zero-copy จะเป็นการเปลี่ยนกระบวนทัศน์จริง ๆ เฉพาะในบางสถานการณ์ เช่นใช้ร่วมกับ mmap() และสำหรับการสื่อสารผ่านเครือข่ายก็ไม่ได้เปลี่ยนไปมากนัก เว้นแต่จะใช้เทคนิคที่แรงอย่าง RDMA
      สำหรับ use case ที่ zero-copy ไม่ได้สำคัญนัก ผมอยากเพิ่ม API ทางเลือกให้ Cap'n Proto อยู่เสมอ โดยให้ใช้ “struct C ธรรมดา” หรือรูปแบบที่ใกล้เคียง แล้วทำซีเรียลไลซ์แบบคัดลอกหนึ่งครั้งเหมือน protobuf แต่ก็ยังไม่ได้ทำ
      อย่างไรก็ดี โดยส่วนตัวแล้วผมสนใจ โปรโตคอล RPC มากกว่าการซีเรียลไลซ์มาก ผมคิดว่าโปรโตคอล RPC เป็นการเปลี่ยนกระบวนทัศน์จริง ๆ ในแทบทุก use case ที่ไม่ใช่เรื่องเล็กน้อย
    • ดูเหมือนคุณหมายถึง flatbuffers ไม่ใช่ protobuf มันกลายเป็นมาตรฐานโดยพฤตินัยแล้ว และในบางที่ก็ใช้ SBE
      อย่างไรก็ดี ปัญหาหลักของการซีเรียลไลซ์แบบไบนารีคือการจัดการเวอร์ชันของสคีมาและข้อความ รวมถึง delta encoding ถ้าไม่สนใจสองเรื่องนี้ การซีเรียลไลซ์ไบนารีแบบแบนก็เป็นเรื่องง่ายมาก
      ไม่มีไลบรารีใดที่ให้คำตอบซึ่งจัดการทั้งสองเรื่องข้างต้นได้ดี
    • ถ้าไม่ต้องใช้สคีมา ผมมองว่า MessagePack ค่อนข้างยอดเยี่ยม。ただการซีเรียลไลซ์ JSON ของ V8 เร็วผิดปกติจน MessagePack ก็เอาชนะได้ยาก และในภาษาอื่น ๆ มันมักเร็วกว่า แถมยังช่วยลดจำนวนไบต์ได้ด้วย
    • fbthrift ยังอยู่ดีมีสุขจนถึงทุกวันนี้
  • ผมชอบไอเดียของ capnp มาตลอด แต่สุดท้ายสิ่งที่ขัดใจคือมันเป็น โปรโตคอลเข้ารหัสข้อความ แต่กลับมีความเห็นไปถึงว่าควรออกแบบสถาปัตยกรรมเซิร์ฟเวอร์ของผมอย่างไร
    gRPC ก็มีปัญหานี้อย่างชัดเจนเหมือนกัน แต่แยกจาก protobuf อย่างชัดมาก และ protobuf เองก็มีฟีเจอร์ที่เกี่ยวกับ gRPC อยู่บ้าง
    ความพัวพันแบบนี้ทำให้ทุกครั้งที่เทียบกับ capnp ผมมักเอนเอียงไปทาง flatbuffers หรือ protobuf โดยเฉพาะเพราะ implementation ของ fb และ pb นั้นเรียบง่ายกว่ามาก และผมให้คุณค่ากับความเรียบง่ายสูงมากในแง่ความปลอดภัยและการบำรุงรักษา
    ผมมองว่าการขาด implementation ภาษา third-party ที่ดี ๆ ก็เป็นสัญญาณโดยตรงว่าการตัดสินแบบนี้สมเหตุสมผลแล้ว bus factor และความอยู่รอดระยะยาวก็แย่มากด้วย ความเรียบง่ายคือผู้ชนะ

    • ปัญหาที่ผมเจอทุกครั้งเวลาจะเข้าไปใช้ cap'n'proto ไม่ใช่แค่มันมีความเห็นต่อสถาปัตยกรรมเซิร์ฟเวอร์เท่านั้น แต่ใน C++ มันยังพา KJ ซึ่งเป็นทางเลือกแทน STL ที่มีแนวทางเฉพาะตัวสูงมากติดมาด้วย ตอนลองจับเมื่อหลายปีก่อน มันยื่นมือเข้าไปแตะหลายส่วนทั่ว codebase เดิม ทำให้ทำงานด้วยยาก
      เวอร์ชัน Rust ก็ต้องการวิถีการใช้ชีวิตตามบรรทัดฐานของตัวเองเช่นกัน หลายอย่างในนั้นสมเหตุสมผลในโลกทัศน์แบบ zero-copy แต่ก็ยังทำให้การแสดงออกหลายแบบยากขึ้น และเอกสารก็อ่านยากด้วย
      ดังนั้นแค่เหตุผลนี้อย่างเดียว ผมก็มักเลือก flatbuffers
      ถึงอย่างนั้นก็หวังว่าสักวันจะมีสถานการณ์ที่ cap'n'proto จำเป็นและมีประโยชน์ และอยากทำโปรเจกต์งานอดิเรกที่ fork ไว้หลายอันตลอดหลายปีเพื่อจะลองใช้มัน ให้เสร็จสักอันก็ยังดี ต้องยอมรับว่ามีงานวิศวกรรมคุณภาพสูงอยู่จริง
    • ผมสงสัยว่าเลเยอร์ serialization ส่งผลต่อ การเลือก RPC อย่างไร
  • ไม่ใช่เรื่องใหม่ แต่สงสัยว่าชื่อนี้เป็นการคารวะ Star Trek Voyager โดยตั้งใจหรือเปล่า หรือมีแหล่งอ้างอิงอื่นที่ผมไม่รู้จัก
    https://memory-alpha.fandom.com/wiki/Captain_Proton

    • จริง ๆ แล้วผมไม่เคยนึกถึงการอ้างอิงนั้นเลย
      ชื่อ Cap'n Proto เดิมทีหมายถึง Capabilities and Protobufs มันเป็นโปรโตคอล RPC แบบ capability-based ที่อิง Protocol Buffers แต่ช่วงต้น ๆ ผมเกิดอยากลองรูปแบบ serialization ที่แตกต่างไปโดยสิ้นเชิง อย่างไรก็ดี “Proto” ก็ยังสื่อถึง protocol ได้อยู่ จึงคงชื่อไว้
      มุกคำว่า “cerealization protocol” จริง ๆ มีคนอื่นบอกผมมา แต่ผมก็เอาไปใส่ในโลโก้ทันที
    • เห็นโปรโมตว่าเป็น “cerealization protocol” เลยคิดมาตลอดว่าเป็นการอ้างอิงถึงซีเรียล Cap'n Crunch
 
bbulbum 2023-07-30

น่าจะเป็น Serialization/RPC มากกว่า เหมือนจะพิมพ์ผิดนะ