วิธีการนำตัวจัดการกระบวนการไปใช้ในการจัดหากิจกรรม


14

ฉันกำลังทำงานกับแอปพลิเคชันตัวอย่างขนาดเล็กเพื่อเรียนรู้แนวคิดของ CQRS และการจัดหากิจกรรม ฉันมีการBasketรวมและการProductรวมซึ่งควรทำงานอย่างอิสระ

นี่คือโค้ดหลอกบางอย่างที่จะแสดงการใช้งาน

Basket { BasketId; OrderLines; Address; }

// basket events
BasketCreated { BasketId; }
ItemAdded { BasketId; ProductId; Quantity }
AddItemSucceeded { BasketId; ProductId; Quantity }
AddItemRevoked { BasketId; ProductId; Quantity }
ItemRemoved { BasketId; ProductId; Quantity }
CheckedOut { BasketId; Address }

Product { ProductId; Name; Price; }

// product events
ProductReserved { ProductId; Quantity }
ProductReservationFailed { ProductId; Quantity }
ProductReservationCancelled { ProductId; Quantity; }

คำสั่งนั้นคล้ายกับเหตุการณ์โดยใช้ชื่อที่จำเป็นและไม่เครียดเกินไป

ตอนนี้งานเหล่านี้ใช้ได้ดีอย่างอิสระ ฉันออกคำสั่งAddItemและจะสร้างItemAddedเหตุการณ์Basketโดยรวมซึ่งทำในสิ่งที่ต้องทำกับสถานะของ 'ตะกร้า' ในทำนองเดียวกันสำหรับผลิตภัณฑ์คำสั่งและกิจกรรมใช้งานได้ดี

ตอนนี้ฉันต้องการรวมสิ่งนี้เข้ากับกระบวนการซึ่งจะเป็นแบบนี้ (ในแง่ของคำสั่งและเหตุการณ์ที่เกิดขึ้น):

ผู้จัดการกระบวนการจะทำสิ่งต่อไปนี้:

on BasketCreated: CreateShoppingProcess
on ItemAdded: ReserveProduct
on ProductReserved: SucceedAddingItem // does nothing, but needs to be there so that the basket knows it can check out
on ProductReservationFailed: RevokeAddItem
on RemoveItem: CancelProductReservation
on Checkout: CreateOrder // create an order and so on...

คำถามที่ฉันไม่สามารถหาคำตอบที่ชัดเจนคือ:

  1. ฉันต้องยืนยันผู้จัดการกระบวนการหรือไม่ ดูเหมือนว่าฉันจะทำ แต่ฉันไม่แน่ใจ
  2. ถ้าเป็นเช่นนั้นฉันจำเป็นต้องบันทึกเหตุการณ์สำหรับผู้จัดการกระบวนการ อย่างไรก็ตามเหตุการณ์ที่ฟังอยู่นั้นเชื่อมโยงกับมวลรวม ฉันจะเพิ่มรหัสกระบวนการในสิ่งเหล่านั้นหรือไม่? ฉันมีกิจกรรมแยกต่างหากสำหรับผู้จัดการกระบวนการหรือไม่ วิธีการทำเช่นนี้และเก็บไว้เป็น DRY เท่าที่จะทำได้
  3. ฉันจะรู้ได้อย่างไรว่าตะกร้าProductReservedเหตุการณ์มีไว้สำหรับอะไร มันตกลงที่จะมีBasketIdในที่เกินไปหรือว่าข้อมูลที่รั่วไหล?
  4. ฉันจะรักษาความสัมพันธ์ระหว่างเหตุการณ์ได้อย่างไรฉันจะทราบได้อย่างไรว่าItemAddedเกิดProductReservedเหตุการณ์ใด ฉันผ่านไปEventIdหรือไม่ ดูเหมือนจะแปลก ...
  5. ฉันควรใช้ตัวBasketจัดการกระบวนการแทนการรวมแบบง่ายหรือไม่?

หลังจากการวิจัยเพิ่มเติมฉันมาที่นี่: Saga เป็นสิ่งที่ทำให้กิจกรรมของตัวเองและฟังเหตุการณ์จากภายนอก โดยทั่วไปมันคือการรวมที่สามารถตอบสนองต่อเหตุการณ์ที่เกิดขึ้นนอกโลกของตัวเอง

Process Manager ทำงานกับเหตุการณ์จากภายนอกและส่งคำสั่ง สามารถสร้างประวัติขึ้นมาใหม่ได้จากเหตุการณ์ที่เกิดขึ้นใน Aggregates ซึ่งแบ่งปันตัวระบุทั่วไปเช่น correlationId


ดูเหมือนว่าคุณกำลังพยายามเข้ารหัสในระบบของคุณซึ่งเป็นกระบวนการอย่างเป็นทางการที่จะทำการถอดความกรณีการใช้งานแบบไม่เป็นทางการที่มีอยู่ซึ่งทำจากชุดคำสั่ง การทำเช่นนั้นดูเหมือนว่าคุณกำลังสร้างคำสั่งและเหตุการณ์ที่ซ้ำซ้อนจำนวนมากนอกเหนือจากคำสั่งที่มีอยู่ นั่นคือความตั้งใจของคุณหรือไม่ ธุรกิจต้องการอะไรในการทำให้เป็นระเบียบในกระบวนการเป็นระเบียบ? อะไรในโดเมนของคุณที่คุณต้องระบุกระบวนการนี้และเหตุผลเกี่ยวกับมันเป็นแนวคิดที่สมบูรณ์?
guillaume31

นี่เป็นโครงการที่ทำขึ้นโดยสิ้นเชิงโดยมีวัตถุประสงค์คือเพื่อเรียนรู้วิธีทำให้มวลรวมที่ค่อนข้างอิสระสองตัวทำงานร่วมกัน ดังนั้นจึงไม่มี "ความต้องการทางธุรกิจ" ที่แท้จริงและฉันพยายามหลีกเลี่ยงความซ้ำซ้อนในคำสั่งและเหตุการณ์เหล่านี้ให้มากที่สุด ดังนั้นความสับสนกับผู้จัดการกระบวนการเนื่องจากดูเหมือนว่าไม่ควรทำซ้ำสิ่งที่มวลรวมกำลังจัดการอยู่แล้ว อย่างไรก็ตามฉันจำเป็นต้องเชื่อมต่อระหว่างมวลรวมทั้งสองนี้อย่างใด ดูเหมือนว่าการใช้สาเหตุและสหสัมพันธ์อาจช่วยได้ แต่ฉันต้องลองดู
Ivan Pintar

คำตอบ:


14

ทบทวนสิ่งที่ Rinat Abdullin เขียนเกี่ยวกับการพัฒนากระบวนการทางธุรกิจ โดยเฉพาะอย่างยิ่งสังเกตคำแนะนำของเขาสำหรับการพัฒนากระบวนการทางธุรกิจในสภาพแวดล้อมที่เปลี่ยนแปลงอย่างรวดเร็วผู้จัดการกระบวนการคือ "เพียง" การแทนที่อัตโนมัติสำหรับมนุษย์ที่จ้องมองที่หน้าจอ

โมเดลจิตของฉันเองของผู้จัดการกระบวนการคือมันเป็นเหตุการณ์ที่ฉายมาซึ่งคุณสามารถสอบถามรายการคำสั่งที่รอดำเนินการ

ฉันต้องยืนยันผู้จัดการกระบวนการหรือไม่ ดูเหมือนว่าฉันจะทำ แต่ฉันไม่แน่ใจ

มันเป็นรูปแบบการอ่าน คุณสามารถสร้างตัวจัดการกระบวนการจากประวัติเหตุการณ์ในแต่ละครั้งที่คุณต้องการ หรือคุณสามารถปฏิบัติต่อมันเหมือนภาพรวมที่คุณอัปเดต

ถ้าเป็นเช่นนั้นฉันจำเป็นต้องบันทึกเหตุการณ์สำหรับผู้จัดการกระบวนการ

ไม่มี - ผู้จัดการกระบวนการเป็นผู้จัดการ มันไม่ได้ทำอะไรที่เป็นประโยชน์ด้วยตัวมันเอง แต่จะบอกให้มวลรวมทำงาน (เช่นเปลี่ยนแปลงสมุดบันทึก)

ฉันจะรู้ได้อย่างไรว่าตะกร้าสินค้าของ ProductReserved นั้นมีไว้สำหรับอะไร เป็นไปได้ไหมที่จะมี BasketId อยู่ด้วยเช่นกันหรือว่าเป็นข้อมูลที่รั่วไหล

แน่ใจ หมายเหตุ:ในโดเมนช็อปปิ้ง "ของจริง" ส่วนใหญ่คุณจะไม่ยืนยันในการจองพื้นที่โฆษณาก่อนประมวลผลคำสั่งซื้อ เพิ่มความขัดแย้งที่ไม่จำเป็นให้กับธุรกิจ มีโอกาสมากขึ้นที่ธุรกิจของคุณจะต้องการยอมรับคำสั่งซื้อจากนั้นขออภัยในกรณีที่ไม่ค่อยพบว่าคำสั่งซื้อไม่สามารถดำเนินการตามเวลาที่กำหนดได้

ฉันจะรักษาความสัมพันธ์ระหว่างเหตุการณ์ได้อย่างไรฉันจะรู้ได้อย่างไรว่า ItemAdded ใดที่สร้างขึ้นโดยใช้ ProductReserved

ข้อความมีข้อมูล meta - โดยเฉพาะคุณสามารถรวม causationIdentifier (เพื่อให้คุณสามารถระบุคำสั่งที่สร้างเหตุการณ์ใด) และcorrelationIdentifierเพื่อติดตามการสนทนาโดยทั่วไป

ตัวอย่างเช่นตัวจัดการกระบวนการเขียน id ของตัวเองเป็น correlationId ในคำสั่ง; เหตุการณ์ที่สร้างขึ้นโดยการคัดลอกรหัสความสัมพันธ์ของคำสั่งและผู้จัดการกระบวนการของคุณสมัครสมาชิกกับเหตุการณ์ทั้งหมดที่มี correlationId ของตัวเอง

ฉันควรใช้ตะกร้าเป็นผู้จัดการกระบวนการแทนที่จะเป็นเรื่องง่ายหรือไม่?

คำแนะนำของฉันคือ แต่อุดีดาฮันมีความคิดเห็นที่ต่างออกไปที่คุณควรตรวจสอบ ซึ่งนั่นคือCQRS นั้นสมเหตุสมผลถ้าการรวมของคุณเป็น sagas - Udi ใช้ saga ในตำแหน่งที่ตัวจัดการกระบวนการกลายเป็นตัวสะกดที่โดดเด่น

ผู้จัดการกระบวนการควรดึงข้อมูลรวม

ไม่จริงเหรอ? ผู้จัดการกระบวนการเกี่ยวข้องกับการประสานเป็นหลักไม่ใช่สถานะโดเมน อินสแตนซ์ของกระบวนการจะมี "สถานะ" ในรูปแบบของประวัติของเหตุการณ์ทั้งหมดที่พวกเขาสังเกตเห็น - สิ่งที่ถูกต้องในการตอบสนองต่อเหตุการณ์ Z ขึ้นอยู่กับว่าเราได้เห็นเหตุการณ์ X และ Y หรือไม่ ดังนั้นคุณอาจจำเป็นต้องสามารถจัดเก็บและโหลดการเป็นตัวแทนของรัฐนั้น (ซึ่งอาจเป็นสิ่งที่แบนหรืออาจเป็นประวัติศาสตร์ของเหตุการณ์ที่สังเกต)

(ฉันพูดว่า "ไม่จริง" เพราะการรวมถูกกำหนดไว้อย่างชัดเจนพอที่จะไม่ผิดอย่างสมบูรณ์ที่จะอ้างว่ารายการของเหตุการณ์ที่สังเกตคือ "รวม" ความแตกต่างนั้นมีความหมายมากกว่าการนำไปใช้ - เราโหลดสถานะกระบวนการแล้วตัดสินใจว่า ส่งไปยังส่วนต่าง ๆ ของระบบที่รับผิดชอบเกี่ยวกับสถานะโดเมนมีบางอย่างเกิดขึ้นที่นี่

ดังนั้น PM จึงไม่จำเป็นต้องใช้การจัดการสถานะแบบหนึ่งกับอีกประเภทหนึ่งเพราะรับผิดชอบเฉพาะการทำสิ่งที่อยู่และไม่เคยอยู่ในระหว่างการรีเพลย์?

ไม่มาก - การจัดการของรัฐไม่ใช่สิ่งที่ต้องทำ ในสถานการณ์ที่ผู้จัดการกระบวนการไม่ควรปล่อยสัญญาณใด ๆ คุณให้การเชื่อมต่อเฉื่อยกับโลก กล่าวอีกนัยหนึ่งdispatch(command)คือไม่มีการเลือก


1
คุณพูดว่า: คุณสามารถสร้างผู้จัดการกระบวนการขึ้นใหม่จากประวัติเหตุการณ์ทุกครั้งที่คุณต้องการ ... แต่เพื่อสร้างใหม่ฉันต้องบันทึกกิจกรรมไว้ หรือฉันควรจะสร้างมันขึ้นมาใหม่จากเหตุการณ์ในมวลรวม? ส่วนที่ฉันต้องดิ้นรนคือกับมวลรวมเหตุการณ์มีรหัสรวมและง่ายต่อการสร้างใหม่โดยการค้นหากิจกรรมทั้งหมดด้วยรหัสรวมนั้น แต่ฉันจะทำอย่างนั้นกับผู้จัดการกระบวนการได้อย่างไร ฉันควรจะทำอย่างนั้นกับผู้จัดการกระบวนการหรือไม่? หรือผู้จัดการกระบวนการควรมองหาการรวมเมื่อจำเป็นต้องตัดสินใจบางสิ่งที่ขึ้นอยู่กับเหตุการณ์ที่เข้ามา?
Ivan Pintar

สิ่งที่ฉันหายไปคือแนวคิดเกี่ยวกับสาเหตุและความสัมพันธ์ในการจัดหางาน เมื่อฉันมองเข้าไปในนั้นแล้วคำตอบของคุณสำหรับคำถามที่สี่ในที่สุดก็ทำให้รู้สึก
Ivan Pintar

1
ฉันจะรักคำตอบของความคิดเห็นแรกของ @IvanPintar; ผู้จัดการกระบวนการควรดึงข้อมูลรวม พวกเขาควรสร้างตัวเองขึ้นอยู่กับเหตุการณ์ที่มันประมวลผล? ในกรณีนั้นผู้จัดงานจะต้องปราศจากผลข้างเคียงใช่ไหม
Jeff

@Jeff ในตัวอย่างหนึ่งที่ฉันทำผู้จัดการกระบวนการมีที่จัดเก็บของตัวเองซึ่งได้รับการอัปเดตกับแต่ละเหตุการณ์ที่ประมวลผลเป็นรูปแบบการอ่าน นี่เป็นเรื่องง่ายที่จะทำและมันก็ง่ายที่จะติดตามสิ่งที่ประมวลผลแล้ว ในอีกตัวอย่างหนึ่งผู้จัดการกระบวนการสร้างและจัดเก็บกิจกรรมของตัวเองซึ่งสร้างขึ้นจากเหตุการณ์รวม คล้ายกับข้างต้น แต่รัฐเป็นเหตุการณ์ที่มา ขึ้นอยู่กับความซับซ้อนของสถานะที่ผู้จัดการกระบวนการเก็บไว้อาจทำได้ง่ายกว่า ฉันพบวิธีแรกง่ายกว่า
Ivan Pintar

น่าสนใจดังนั้นมันจึงขึ้นอยู่กับนักพัฒนาตราบใดที่ผู้จัดการกระบวนการตอบสนองต่อเหตุการณ์และส่งคำสั่งในที่สุด?
Jeff

2

สิ่งที่คุณกำลังมองหามีรูปแบบที่เรียกว่า "Saga" ซึ่งเป็นตัวจัดการกระบวนการ

Saga นั้นสมบูรณ์แบบสำหรับกระบวนการทำงานที่ยาวนานเช่นกันเพราะสามารถรักษาสถานะระหว่างคำสั่งที่สัมพันธ์กันได้

นี่เป็นบทความที่ดีเกี่ยวกับ Sagas

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.