ไลบรารีใหม่สำหรับการประมวลผลเบื้องหลังใน .NET ชื่อ BusyBee ได้ดึงดูดความสนใจจากนักพัฒนา แต่ไม่ใช่ทุกคนที่เชื่อว่าไลบรารีนี้ให้คุณค่าเพียงพอเมื่อเทียบกับโซลูชันที่มีอยู่แล้ว ไลบรารีที่ให้ wrapper รอบ .NET Channels สำหรับจัดการงานเบื้องหลัง ได้จุดประกายการสนทนาที่น่าสนใจเกี่ยวกับเวลาที่ควรใช้ abstraction เทียบกับการสร้างโดยตรงด้วยเครื่องมือระดับล่าง
คำถามเรื่องสถาปัตยกรรมหลัก
การถกเถียงหลักมุ่งเน้นไปที่ว่า abstraction ของ BusyBee เหนือ .NET Channels นั้นจำเป็นหรือไม่ นักพัฒนาบางคนโต้แย้งว่า Channels นั้นใช้งานง่ายพอแล้วที่จะใช้โดยตรง จึงตั้งคำถามถึงความจำเป็นของเลเยอร์เพิ่มเติม ไลบรารีใช้ semaphore แบบชัดเจนสำหรับควบคุม concurrency ซึ่งได้รับการวิจารณ์จากนักพัฒนาที่ชอบแนวทางระดับสูงกว่า เช่น Parallel.ForEachAsync
รวมกับเมธอด ReadAllAsync
ของ Channel
นักพัฒนาคนหนึ่งได้เน้นความกังวลสำคัญเกี่ยวกับแนวทาง semaphore โดยสังเกตว่าการปล่อย semaphore ในคลาสที่แตกต่างจากที่ได้รับมา อาจนำไปสู่ปัญหาการบำรุงรักษาเมื่อทีมแก้ไขโค้ดในภายหลัง สิ่งนี้สัมพันธ์กับหลักการที่กว้างขึ้นในการเขียนโปรแกรมแบบ concurrent คือการใช้ abstraction ระดับสูงสุดที่เหมาะกับปัญหา
ตัวเลือกการกำหนดค่า Queue:
- Unbounded Queue: ไม่มีข้อจำกัดด้านความจุ
- Bounded Queue: พร้อมกลยุทธ์การจัดการ overflow รวมถึง Wait, Ignore, ThrowException, DiscardOldest และ DiscardNewest
- การควบคุม Parallelism: สามารถกำหนดจำนวน job slot ที่ทำงานพร้อมกันได้
- การจัดการ Timeout: timeout ระดับ global พร้อมความสามารถในการ override แต่ละ job
การวางตำแหน่งเทียบกับโซลูชันที่มีอยู่แล้ว
BusyBee เผชิญคำถามเกี่ยวกับตำแหน่งในระบบนิเวศ .NET โดยเฉพาะเมื่อเปรียบเทียบกับเครื่องมือที่มีชื่อเสียงมากกว่า นักพัฒนาได้เปรียบเทียบกับ Hangfire ซึ่งเป็นไลบรารีจัดกำหนดการงานที่ได้รับความนิยม และยังตั้งคำถามว่าให้ประโยชน์เหนือคลาส BackgroundService ที่มีอยู่แล้วหรือไม่ ความแตกต่างหลักอยู่ที่ขอบเขตและการเก็บข้อมูล ในขณะที่ Hangfire เสนอการเก็บข้อมูลในฐานข้อมูลและความสามารถในการจัดกำหนดการ BusyBee มุ่งเน้นไปที่การประมวลผลในหน่วยความจำเพียงอย่างเดียวสำหรับงานเบื้องหลังที่ต้องการทันที
ผู้สร้างไลบรารีอธิบายว่า BusyBee เติมเต็มช่องว่างเฉพาะ คือการประมวลผลเบื้องหลังที่เบาโดยไม่มี dependency ภายนอก ออกแบบมาสำหรับสถานการณ์เช่นการประมวลผลการอัปโหลดไฟล์แบบ asynchronous หลังจากที่ API request ส่งคืนแล้ว มากกว่างานที่มีกำหนดการซึ่งต้องอยู่รอดจากการรีสตาร์ตแอปพลิเคชัน
การเปรียบเทียบกับทางเลือกอื่น:
โซลูชัน | การเก็บข้อมูลถาวร | การจัดตารางเวลา | ความซับซ้อน | กรณีการใช้งาน |
---|---|---|---|---|
BusyBee | ในหน่วยความจำเท่านั้น | การดำเนินการทันที | ต่ำ | งานพื้นหลังแบบง่าย |
Hangfire | รองรับฐานข้อมูล | รองรับการจัดตารางเวลาแบบเต็มรูปแบบ | ปานกลาง-สูง | การจัดการงานในองค์กร |
BackgroundService | ปรับแต่งได้ | ต้องพัฒนาเอง | ปานกลาง | บริการพื้นหลังแบบกำหนดเอง |
Raw Channels | ในหน่วยความจำ | ต้องพัฒนาเอง | ต่ำ-ปานกลาง | สถานการณ์ที่ต้องการควบคุมโดยตรง |
ข้อเสนอคุณค่าในทางปฏิบัติ
แม้จะมีการถกเถียงทางเทคนิค ไลบรารีนี้ก็แก้ไขปัญหาในโลกจริงที่หลายทีมพัฒนาเผชิญ แทนที่จะสร้างตรรกะการประมวลผลเบื้องหลังที่คล้ายกันซ้ำแล้วซ้ำเล่าในโครงการต่างๆ BusyBee รวบรวมความต้องการทั่วไป เช่น การจัดการ graceful shutdown การรวม OpenTelemetry และการสนับสนุน timeout ไว้ในคอมโพเนนต์ที่ใช้ซ้ำได้
ทีมของฉันพบว่าเราต้องสร้างสิ่งที่คล้ายกันด้วยตัวเองเกือบทุกครั้งที่เราเริ่มโครงการใหม่ หากเราต้องการมันอยู่เรื่อยๆ ฉันคิดว่าน่าจะมีคนอื่นๆ ที่อยู่ในสถานการณ์เดียวกัน
อย่างไรก็ตาม นักพัฒนาบางคนยังคงสงสัยเกี่ยวกับการเพิ่ม dependency ภายนอกสำหรับฟังก์ชันที่พวกเขาสามารถสร้างเองได้ โดยชอบที่จะรักษาการควบคุมตรรกะการประมวลผลเบื้องหลังของตัวเอง
คุณสมบัติหลักของ BusyBee :
- คิวในหน่วยความจำที่สร้างบน .NET Channels
- การกำหนดค่าการหมดเวลาของงาน (ทั้งแบบทั่วไปและต่องาน)
- การประมวลผลแบบขนานพร้อมการกำหนดค่าการทำงานพร้อมกัน
- การรวมเข้ากับ OpenTelemetry สำหรับเมตริกและการติดตาม
- กลยุทธ์การล้นหลายแบบสำหรับคิวที่มีขอบเขตจำกัด
- การจัดการการปิดระบบแบบสง่างาม
การสนทนาเรื่องระบบนิเวศ .NET ในวงกว้าง
การสนทนาเรื่อง BusyBee ยังเน้นให้เห็นว่านักพัฒนาหลายคนไม่ทราบความสามารถที่มีอยู่แล้วใน .NET อย่างเต็มที่ บางคนกล่าวถึงทางเลือกอื่น เช่น TPL Dataflow ซึ่งยังคงไม่ได้รับการใช้งานเต็มที่แม้จะเป็นส่วนหนึ่งของเฟรมเวิร์ก คนอื่นๆ แบ่งปันแนวทางของตัวเอง เช่น การใช้ PostgreSQL กับ SELECT FOR UPDATE SKIP LOCKED
สำหรับการจัดการคิว
สิ่งนี้สะท้อนความท้าทายทั่วไปในระบบนิเวศที่อุดมไปด้วยเครื่องมือเช่น .NET ด้วยเครื่องมือที่มีอยู่แล้วมากมาย นักพัฒนาบางครั้งสร้างโซลูชันสำหรับปัญหาที่มีคำตอบในระดับเฟรมเวิร์กอยู่แล้ว การถกเถียงเรื่อง BusyBee โดยพื้นฐานแล้วสรุปได้ว่าความสะดวกสบายและการมาตรฐานนั้นสมควรกับการเพิ่ม dependency อีกตัวหรือไม่ หรือว่าเครื่องมือที่มีอยู่แล้วนั้นเพียงพอสำหรับกรณีการใช้งานส่วนใหญ่
อ้างอิง: BusyBee