1 คะแนน โดย GN⁺ 3 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในช่วง 6 เดือนที่ผ่านมา crates.io ได้เปิดตัว ตัวดูซอร์สโค้ด สำหรับตรวจสอบแพ็กเกจที่เผยแพร่โดยตรง และระบบบัญชีที่เป็นอิสระจาก GitHub พร้อมทั้งเพิ่มคำแนะนำด้านความปลอดภัยและการแทนที่ด้วยไลบรารีมาตรฐาน
  • แท็บ Code ใหม่รองรับการค้นหาไฟล์ การไฮไลต์ไวยากรณ์ และการเลือกบรรทัดที่แชร์ได้ โดยโหลดเฉพาะไฟล์ที่จำเป็นผ่าน ZIP และ JSON manifest บน CDN รวมถึง HTTP range requests โดยไม่เพิ่มภาระให้ API server
  • ตาม RFC #3946 ได้เริ่มการติดตั้งใช้งาน ชื่อผู้ใช้เฉพาะของ crates.io และมีแผนจะรองรับผู้ให้บริการยืนยันตัวตนนอกเหนือจาก GitHub ในอนาคต หลังจากรองรับการเปลี่ยนชื่อผู้ใช้และผ่านการตรวจสอบด้านความปลอดภัย
  • ย้ายฟรอนต์เอนด์จาก Ember.js ไปเป็น Svelte อย่างสมบูรณ์แล้ว และปรับปรุงการค้นหา การดู reverse dependencies การแคช CDN และการประมวลผล Git index ให้มีประสิทธิภาพและเสถียรภาพสูงขึ้น
  • แสดงคำเตือนแพ็กเกจที่ RustSec ระบุว่าเลิกบำรุงรักษาแล้ว และ API ทางเลือกในไลบรารีมาตรฐาน เช่น std::sync::LazyLock บนหน้าแพ็กเกจ เพื่อช่วยตรวจสอบ dependencies และลด dependencies ที่ไม่จำเป็น

ตัวดูซอร์สโค้ดสำหรับตรวจสอบแพ็กเกจที่เผยแพร่

  • แท็บ Code ใหม่บนหน้าแพ็กเกจช่วยให้สำรวจไฟล์ของแต่ละเวอร์ชันที่เผยแพร่ได้ภายใน crates.io
    • แสดงไฟล์ที่ cargo ดาวน์โหลดจริงเมื่อเพิ่ม dependency ไม่ใช่ repository ที่เชื่อมโยงไว้
    • ตรวจสอบไฟล์ที่ไม่มีใน repository ได้ เช่น Cargo.toml ที่ถูกทำให้เป็นมาตรฐานโดย cargo จึงทำให้การ audit dependencies ง่ายขึ้น
  • ตัวดูรองรับ การค้นหาใน file tree การไฮไลต์ไวยากรณ์ และการเลือกบรรทัดแบบ GitHub
    • เมื่อคลิกหรือลากที่หมายเลขบรรทัด จะสร้าง URL ที่แชร์ได้ในรูปแบบ #L10-L20
  • เซิร์ฟเวอร์สร้างไฟล์ ZIP และ JSON manifest ที่อธิบายโครงสร้างไฟล์สำหรับทุกเวอร์ชันที่เผยแพร่
    • ไฟล์ .crate ที่ cargo ใช้เป็น tarball บีบอัดด้วย gzip ซึ่งไม่รองรับการเข้าถึงแบบสุ่ม จึงมีงานเบื้องหลัง repackaging ให้เป็น ZIP ที่สำรวจได้
    • ZIP และ manifest ถูกให้บริการผ่าน CDN แบบ static
    • ฟรอนต์เอนด์จะรับ manifest ก่อน แล้วโหลดแต่ละไฟล์เฉพาะเมื่อต้องใช้ผ่าน HTTP range requests
    • การสำรวจซอร์สแทบไม่เพิ่มภาระให้ crates.io API server และยังรองรับไปถึง release เก่า ๆ ด้วยการประมวลผลเวอร์ชันเดิมทั้งหมดแบบ batch
  • ไลบรารีเรนเดอร์ของตัวดูโค้ดเดิมเป็น ตัวเรนเดอร์ diff และกำลังพัฒนาตัวดูเปรียบเทียบระหว่างเวอร์ชันโดยใช้ infrastructure เดียวกัน
    • เมื่อเสร็จแล้ว จะสามารถตรวจสอบการเปลี่ยนแปลงที่แน่นอนระหว่างสองเวอร์ชันที่เผยแพร่บน crates.io ได้

บัญชี crates.io ที่เป็นอิสระจาก GitHub

  • ทีม crates.io อนุมัติ RFC #3946 เมื่อปลายเดือนพฤษภาคม
  • เดิมทีการเข้าสู่ระบบด้วย GitHub และตัวตนบน crates.io ผูกกันอย่างแน่นหนา ชื่อผู้ใช้จึงถูกกำหนดโดยบัญชี GitHub แต่ RFC นี้นำ ชื่อผู้ใช้เฉพาะของ crates.io ที่เป็นอิสระจากบัญชีที่เชื่อมโยงไว้มาใช้
  • ชื่อผู้ใช้เฉพาะนี้เป็นเงื่อนไขเบื้องต้นสำหรับการรองรับการเข้าสู่ระบบผ่านผู้ให้บริการยืนยันตัวตนนอกเหนือจาก GitHub ในอนาคต
  • เริ่มการติดตั้งใช้งานแล้ว แต่ฟีเจอร์หลักที่ผู้ใช้จะเห็นได้และยังไม่เสร็จคือ การเปลี่ยนชื่อผู้ใช้
    • หลังจากทำส่วนนี้เสร็จ จะเดินหน้า RFC เพิ่มเติมและการติดตั้งใช้งานสำหรับการเข้าสู่ระบบผ่านผู้ให้บริการยืนยันตัวตนรายอื่น
    • เนื่องจากส่งผลโดยตรงต่อการยืนยันตัวตนและความปลอดภัยของบัญชี จึงจะค่อย ๆ rollout เป็นขั้นตอนเล็ก ๆ ที่ผ่านการตรวจสอบอย่างรอบคอบ

คำแนะนำด้านความปลอดภัยและการแทนที่ด้วยไลบรารีมาตรฐาน

  • แท็บ Security เดิมแสดงคำแนะนำด้านความปลอดภัยจากฐานข้อมูล RustSec และตอนนี้แพ็กเกจที่ RustSec ทำเครื่องหมายว่าเลิกบำรุงรักษาแล้วจะแสดง แบนเนอร์คำเตือน ที่ด้านบนของหน้าด้วย
    • จากแบนเนอร์สามารถไปยังคำแนะนำนั้น ๆ ซึ่งมีรายละเอียดและทางเลือกที่เป็นไปได้
  • แพ็กเกจที่ฟังก์ชันถูกดูดซับเข้าไปในไลบรารีมาตรฐานแล้วจะแสดงแบนเนอร์ “You might not need this dependency
    • เช่น lazy_static สามารถแทนที่ได้ด้วย std::sync::LazyLock ตั้งแต่ Rust 1.80
    • ในรายการ dependencies แพ็กเกจที่มีตัวแทนแล้วจะมีไอคอนหลอดไฟขนาดเล็กที่ให้คำแนะนำเดียวกัน
  • ข้อมูลที่เกี่ยวข้องถูกจัดการใน repository ใหม่ rust-lang/std-replacement-data
    • อนุญาตเฉพาะรายการที่แทนที่ด้วยไลบรารีมาตรฐานเท่านั้น
    • ทุกรายการต้องอ้างอิง API ของ std, core, alloc ที่เสถียรแล้ว และเวอร์ชัน Rust ที่เกี่ยวข้อง
    • ก่อนเพิ่มรายการ จะต้องแจ้งผู้ดูแลแพ็กเกจและให้ช่วงเวลาสำหรับแสดงความคิดเห็น
    • สามารถเสนอรายการใหม่ใน repository ได้ และข้อมูลที่สะสมไว้สามารถนำไปใช้ในเครื่องมืออื่น ๆ ได้ด้วย

ย้ายฟรอนต์เอนด์ไป Svelte เสร็จสมบูรณ์

  • การทดลองย้ายฟรอนต์เอนด์ crates.io จาก Ember.js ไปยัง Svelte เสร็จสิ้นอย่างประสบความสำเร็จ
    • ฟรอนต์เอนด์ใหม่ไปถึงระดับที่เทียบเท่าฟีเจอร์เดิมแล้ว
    • หลังจาก ทดสอบสาธารณะ ในเดือนเมษายน ได้เปลี่ยนเป็นฟรอนต์เอนด์เริ่มต้นเมื่อต้นเดือนพฤษภาคม
    • แอปพลิเคชัน Ember.js ถูกนำออกจาก repository แล้ว
  • เป็น การย้ายแบบหนึ่งต่อหนึ่ง ที่คงดีไซน์และฟีเจอร์เดิมไว้ เพื่อออกแบบให้ผู้ใช้ไม่รู้สึกถึงการเปลี่ยนแปลง
  • ทีมและผู้ร่วมพัฒนาสามารถใช้เฟรมเวิร์กสมัยใหม่ ลดกำแพงการเข้ามามีส่วนร่วมของผู้ร่วมพัฒนาใหม่ และเพิ่มความเร็วในการพัฒนาแบบวนซ้ำได้ โดยตัวดูซอร์สโค้ดเป็นตัวอย่างหนึ่ง
  • ขอขอบคุณทั้งทีม Ember.js ที่ crates.io ใช้มาหลายปี และทีม Svelte ที่สนับสนุนการเปลี่ยนผ่าน

หน้า error ของ Ferris

  • Ferris บนหน้า error ของ crates.io ถูกปรับให้ใช้ดวงตามองตามเคอร์เซอร์เมาส์
  • หน้า error 404 ก็มี interaction เล็ก ๆ ให้ใช้งาน

ประสิทธิภาพการค้นหาและการดู reverse dependencies

  • การค้นหาเรียงตามความเกี่ยวข้องก่อนหน้านี้คำนวณอันดับของทุกแพ็กเกจที่ตรงกับคำค้นหา จึงอาจใช้เวลา 1–2 วินาที สำหรับคำค้นหาสั้น ๆ หรือคำที่พบบ่อย
    • ตอนนี้จำกัดขอบเขตการคำนวณอันดับไว้ที่แพ็กเกจที่ตรงกัน 1,000 รายการซึ่งมียอดดาวน์โหลดล่าสุดสูงสุด
  • endpoint ของ reverse dependencies จะไม่คำนวณชุดแพ็กเกจที่พึ่งพาทั้งหมดใหม่ในทุก request
    • ให้ผลลัพธ์จาก ตารางที่คำนวณไว้ล่วงหน้า ซึ่งซิงก์ด้วย database trigger
    • เปลี่ยน join ที่มีต้นทุนสูงให้เป็นการ scan index แบบจำกัด ลดโอกาส timeout ลงอย่างมาก

เอกสารสถาปัตยกรรมและการเรนเดอร์ Markdown

  • ปรับปรุง ARCHITECTURE.md ครั้งใหญ่ โดยจัดโครงสร้างรอบระบบระดับบนของ crates.io และวิธีที่ระบบเหล่านั้นเชื่อมต่อกัน
    • กระบวนการที่เกิดขึ้นเมื่อรัน cargo publish
    • เหตุผลที่การดาวน์โหลดแพ็กเกจทั่วไปไม่ผ่าน API server
    • วิธีคำนวณจำนวนดาวน์โหลดจาก access logs ของ CDN
  • README รองรับการเรนเดอร์ definition lists ซึ่งเป็นส่วนขยาย Markdown ที่ใช้กันแพร่หลาย
    • Markdown renderer comrak รองรับ definition lists อยู่แล้ว แต่ส่วนขยายนี้ยังไม่ได้ถูกเปิดใช้งาน

ปรับปรุงประสิทธิภาพแคช CDN

  • เพิ่ม metadata ของ cache tags ให้ไฟล์ที่อัปโหลดไปยัง CDN แบบ static
    • แทนที่จะส่งคำขอ invalidate แยกตาม URL ของแต่ละไฟล์ สามารถ invalidate ไฟล์แคชทั้งหมดของแพ็กเกจหรือ release ใด ๆ ได้ในครั้งเดียว
  • นำ response header ทั่วทั้งระบบ Vary: Cookie ที่ขัดขวางการแคชบน CDN ของ response จาก public API และ asset ของฟรอนต์เอนด์ออก
    • สำหรับ response เฉพาะผู้ใช้ จะใช้ Cache-Control: no-store แทน
    • ส่งผลให้ cache hit rate ที่ CDN edge ดีขึ้น

การเข้าถึงและการประมวลผล Git index

  • ปรับปรุง accessibility ของ crates.io สำหรับผู้ใช้ screen reader
    • ซ่อนไอคอนตกแต่งออกจาก accessibility tree
    • แก้ไขลำดับชั้นของหัวข้อ
    • ใช้ list markup ที่ถูกต้องกับรายการ
    • นำ ARIA snapshot tests มาใช้เพื่อป้องกันไม่ให้ regression หลุดเข้ามาโดยตรวจไม่พบ
    • มีแผนจะปรับปรุง accessibility ต่อเนื่องในอีกหลายเดือนข้างหน้า
  • เปลี่ยนสำเนา local Git index ของ background worker เป็น bare, shallow repository
    • ลบไฟล์ checkout ประมาณ 250,000 ไฟล์และประวัติ commit ทั้งหมดออกจากดิสก์
    • ปรับปรุงประสิทธิภาพการประมวลผลในสถานการณ์ที่ความถี่การเผยแพร่แพ็กเกจเพิ่มขึ้น
  • การ squash index เป็นระยะ ๆ ใช้ GitHub API แทนการสร้าง Git pack ขนาดใหญ่ในเครื่อง
    • วิธีสร้าง local pack แบบเดิมเคยทำให้ worker ใน production หน่วยความจำไม่พอ

ช่องทาง feedback

  • สามารถส่งความคิดเห็นและคำถามเกี่ยวกับ crates.io ได้ที่ Zulip หรือ GitHub Discussions

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

 
GN⁺ 3 시간 전
ความคิดเห็นจาก Lobste.rs
  • ดีใจที่กำลังมีงานเพื่อ แยกบัญชี crates.io ออกจาก GitHub

    • เมื่อก่อนชอบฟีเจอร์ล็อกอินด้วยบัญชี GitHub ในหลายบริการ แต่ตอนนี้รู้สึกว่ามันน่าสนใจน้อยลงแล้ว Tailscale รองรับ ผู้ให้บริการตัวตน OIDC จึงตั้งค่าให้ล็อกอินด้วย Codeberg และ WebFinger บนโดเมนของตัวเอง
      หากต้องการล็อกอินด้วยอีเมลบนโดเมนของตัวเอง example@example.com ให้ใส่ไฟล์ JSON ไว้ที่ https://example.com/.well-known/webfinger โดยมี subject เป็น acct:example@example.com และมี href ของผู้ออก OpenID Connect เป็น https://codeberg.org
      ในการตั้งค่า Codeberg ให้สร้างแอปพลิเคชัน OAuth2 ที่มี URI สำหรับรีไดเรกต์เป็น https://login.tailscale.com/a/oauth_response แล้วนำ Client ID และ Client Secret ที่ออกให้ไปกรอกใน Tailscale ก็น่าจะพอ ต่อไป crates.io ก็น่าจะมีวิธีคล้ายกัน
  • ไม่รู้มาก่อนเลยว่าช่วงหลัง crates.io ปรับปรุงไปมาก ขนาดนี้ ปกติจะค้นจาก lib.rs ก่อน แต่ไม่นานนิสัยอาจเปลี่ยนก็ได้ และการเปลี่ยนแปลงที่ชอบที่สุดคือ Ferris

    • สงสัยว่าการปรับปรุงเหล่านี้มีสัดส่วนมากแค่ไหนที่เป็นผลจาก การนำเอเจนต์มาใช้
  • การเปลี่ยนแปลงดวงตาของ Ferris ดูไม่สมเหตุสมผลในเชิงฟิสิกส์ ส่วนสีขาวบนดวงตาสีดำคือ ไฮไลต์จากการสะท้อนแบบกระจก และถ้าเคอร์เซอร์เมาส์เป็นแหล่งกำเนิดแสง ก็ยากจะเรียกว่าเป็นการทำให้ดวงตามองตามเคอร์เซอร์ได้

  • เวลาตรวจสอบ dependency จะเริ่มจากการทำ symbolic link ~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ ไปที่ ~/cargosrc เพื่อให้เข้าถึงไฟล์ที่ Cargo ดาวน์โหลดมาได้ง่าย
    สำหรับ dependency แต่ละตัวที่จะตรวจสอบ จะ clone Git repository แล้ว checkout เวอร์ชันเป้าหมาย ลบไฟล์ที่ถูกติดตามอยู่ในเครื่อง จากนั้นส่ง SIGSTOP ไปยังโปรเซส rust-analyzer เพิ่ม dependency ใน Cargo.toml ของโปรเจกต์แล้วรัน cargo fetch จากนั้นคัดลอกเนื้อหาในไดเรกทอรี $dependency-$version ที่ดาวน์โหลดมาไปยัง repository ที่ clone ไว้ commit แล้วตรวจสอบ diff ด้วย Git history viewer
    เมื่อตรวจสอบเสร็จ จะใช้สคริปต์บันทึกชุด dependency·เวอร์ชัน·แฮชใน Cargo.lock ลงในฐานข้อมูลที่เชื่อถือได้ เพื่อไม่ต้องตรวจเวอร์ชันเดิมซ้ำ ขั้นตอนดูซับซ้อนก็จริง แต่ส่วนใหญ่ทำอัตโนมัติไว้แล้ว จึงมีประสิทธิภาพกว่าเว็บ UI และถ้า Cargo รองรับ กระบวนการตรวจสอบ แบบนี้จาก command line ได้ก็คงดี สงสัยด้วยว่ามีปลั๊กอินที่ช่วยการตรวจสอบโดยตรง มากกว่าเครื่องมืออย่าง cargo-crev หรือไม่

  • การใช้งานที่ให้ frontend ดึงเฉพาะ manifest มาก่อน แล้วค่อยโหลดแต่ละไฟล์เมื่อจำเป็นด้วย HTTP range request อยู่ที่ นี่ และใช้ DecompressionStream ที่มีในเบราว์เซอร์