เหตุการณ์โดเมน
เหตุการณ์โดเมนคืออะไร
หัวข้อที่มีชื่อว่า “เหตุการณ์โดเมนคืออะไร”เหตุการณ์โดเมนคือกลไกการแยกส่วนที่ทำให้ฟีเจอร์ต่างๆ สื่อสารกันได้โดยไม่ต้อง พึ่งพากันโดยตรง แทนที่ฟีเจอร์ A จะเรียกฟีเจอร์ B ฟีเจอร์ A จะเผยแพร่เหตุการณ์ และฟีเจอร์ B จะสมัครรับเหตุการณ์นั้น
DomainEventBus เป็นบัสเผยแพร่/สมัครรับแบบกระจายสัญญาณภายในโปรเซส ผู้เผยแพร่
เรียก publish(event) ส่วนผู้สมัครรับบริโภคสตรีม on<T>() ที่มีชนิดกำกับ
ทุกเหตุการณ์อิมพลีเมนต์ DomainEvent และพก occurredAt มาด้วย
บัสทำงานอยู่ภายใน cc_server ผู้เผยแพร่ทุกตัวและผู้สมัครรับที่มีชีวิตทุกตัว
อยู่ที่นั่น ไม่มีไคลเอนต์ใดเห็นบัสนี้ สิ่งที่ไคลเอนต์เห็นคือชุดย่อยที่คัดสรรมาแล้ว
ซึ่งเซิร์ฟเวอร์ส่งซ้ำออกมาเป็นเฟรม JSON-RPC notifications/*
ทำไมต้องมีบัสเลย
หัวข้อที่มีชื่อว่า “ทำไมต้องมีบัสเลย”ถ้าไม่มีเหตุการณ์ ปฏิกิริยาข้ามฟีเจอร์ทุกอย่างก็คือการอิมพอร์ต เส้นทางการแจ้งเตือน จะต้องอิมพอร์ตฟีเจอร์เอเจนต์ ฟีเจอร์ pull request ระบบตั๋วงาน และการประชุม เพียงเพื่อให้รู้ว่าควรเด้งการแจ้งเตือนเมื่อใด — แล้วแต่ละฟีเจอร์เหล่านั้นก็จะต้อง รู้ว่ามีการแจ้งเตือนอยู่ ระบบตั๋วงานจะต้องอิมพอร์ตไปป์ไลน์ เพื่อให้ตั๋วงานที่เสร็จแล้ว ผลักดันการรันต่อได้ กราฟการพึ่งพาจะมัดกันเป็นปม และเคอร์เนลที่ใช้ร่วมกันก็เลิก เป็นสิ่งที่ใช้ร่วมกัน
การเผยแพร่เหตุการณ์ตัดวงจรนั้นออกไป เส้นทางการแจ้งเตือนสมัครรับคลาสเหตุการณ์ ยี่สิบเอ็ดคลาส และไม่ต้องอิมพอร์ตฟีเจอร์ใดที่ปล่อยเหตุการณ์เหล่านั้นเลย ตัวสั่งการ ทริกเกอร์ไปป์ไลน์สมัครรับจากทั้งบัสและไม่รู้อะไรเลยเกี่ยวกับ pull request ตั๋วงาน หรือการประชุม ส่วนการรวมข้อมูลของการสังเกตการณ์ก็สรุปผลการรันได้โดยไม่ต้อง ยื่นมือเข้าไปในตัวดิสนพัตเชอร์
ต้นทุนที่ต้องจ่ายก็คือแบบที่คุ้นเคย: ผู้เผยแพร่บอกไม่ได้ว่ามีใครฟังอยู่หรือไม่
และผู้ฟังที่ไม่เคยถูกสร้างขึ้นมาก็เงียบงันอยู่เฉยๆ โดยไม่มีใครรู้ TicketRemoteSyncHandler
คือตัวอย่างที่ยืนยง: มันถูกประกาศไว้ มีเทสต์ครอบคลุม แต่ไม่เคยถูกต่อเข้าใน
โปรดักชัน
สิ่งที่บัสไม่ได้เป็น
หัวข้อที่มีชื่อว่า “สิ่งที่บัสไม่ได้เป็น”คุ้มค่าที่จะพูดให้ชัดเจนเกี่ยวกับสิ่งหนึ่งที่บัสไม่ได้เป็นเจ้าของ
ร่องรอยการตรวจสอบไม่ใช่ภาพฉายของสตรีมเหตุการณ์ ทุกการดำเนินการ RPC
ที่เปลี่ยนแปลงข้อมูลจะถูกตรวจสอบเป็นค่าเริ่มต้น — RepoOp.audited มีค่าเริ่มต้น
เป็น true และการดำเนินการจะเลือกไม่ถูกตรวจสอบก็ต่อเมื่อประกาศ audited: false
ซึ่งเป็นการกระทำที่จงใจและมองเห็นได้บนตัวการดำเนินการนั้นเอง ตัวดิสนพัตเชอร์
ผนวกรายการ “ใครทำอะไร จากที่ไหน” เข้าไปโดยตรงหลังการเรียกที่สำเร็จ ไม่มี
DomainEventAuditBridge ActivityLogPersister เขียนแถว activity_log จาก
เหตุการณ์ ActivityLogged ซึ่งเป็นฟีดแยกต่างหากจากการตรวจสอบ RPC
บัสเหตุการณ์ คือ ช่องทางขนส่งสำหรับการแจ้งเตือนและสำหรับระบบอัตโนมัติ แต่ไม่ใช่ระบบบันทึกหลัก
สิ่งที่บัสขับเคลื่อน
หัวข้อที่มีชื่อว่า “สิ่งที่บัสขับเคลื่อน”- การแจ้งเตือน คลาสเหตุการณ์ยี่สิบเอ็ดคลาสถูกเซิร์ฟเวอร์เปลี่ยนเป็นเฟรมบนสาย
notifications/*บันทึกลงฟีดแบบคงทนต่อเวิร์กสเปซ และกระจายไปยังเซสชันที่เชื่อมต่อ อยู่ เฟรมใดที่มีworkspace_idชี้ไปยังเวิร์กสเปซที่ผู้ใช้ของเซสชันไม่ได้เป็น สมาชิกจะถูกทิ้งที่เซิร์ฟเวอร์ จากนั้นไคลเอนต์จึงกรองส่วนที่เหลือให้เหลือเฉพาะ เวิร์กสเปซที่กำลังดูอยู่ - ระบบอัตโนมัติที่ขับเคลื่อนด้วยเหตุการณ์ ทริกเกอร์ไปป์ไลน์สมัครรับจากบัส และเริ่มไปป์ไลน์ที่ตรงกันโดยอัตโนมัติ (ดูด้านล่าง)
- ปฏิกิริยาตามวงจรชีวิต การสร้างเวิร์กสเปซจะตั้งต้นเอเจนต์ CEO และเอเจนต์ ผู้เชี่ยวชาญ เทมเพลตไปป์ไลน์ที่มีมาให้ในตัว และชุดการประเมินเริ่มต้น การรัน เอเจนต์ที่เสร็จสมบูรณ์จะทำขั้นตอนไปป์ไลน์ที่ถูกระงับไว้ให้ดำเนินต่อ ปิดงาน ป้อนข้อมูลให้ผู้ดูแลเป้าหมาย ปลุกตัวตรวจที่ระบุชื่อไว้ได้ และทริกเกอร์หัวหน้าทีม ซ้ำได้ PR ที่ถูกรวมหรือสเปซที่ถูกลบจะทริกเกอร์การเก็บกวาด worktree
- การซิงค์ข้ามผู้ให้บริการ การเปลี่ยนแปลงตั๋วงานภายในเครื่องถูกส่งออกไปยัง ผู้ให้บริการที่กำหนดค่าไว้ โดยตัวประสานงานที่ฟังเหตุการณ์ตั๋วงานห้าเหตุการณ์
หมวดหมู่ของเหตุการณ์
หัวข้อที่มีชื่อว่า “หมวดหมู่ของเหตุการณ์”เหตุการณ์ครอบคลุมพื้นผิวทั้งผลิตภัณฑ์ ในภาพรวม:
- เวิร์กสเปซ เอเจนต์ และรีโป — การสร้างเวิร์กสเปซ การรันเสร็จสมบูรณ์ การลงทะเบียนรีโป การอัปเดตสกิล
- Pull request — การเผยแพร่ การเปลี่ยนสถานะ การรวม คำขอรีวิว การถูกกล่าวถึง การเฝ้าดู PR ที่คุณเปิดไว้ และ PR ที่ตรวจพบจากภายนอก
- การรับส่งข้อความ — ข้อความ สเปซ และความคืบหน้าการจัดเตรียมสเปซ
- ตั๋วงาน — สร้าง มอบหมาย มอบหมายใหม่ รายละเอียด สถานะ และผลลัพธ์ขั้นสุดท้ายทั้งสามอย่าง
- งาน — เฟรมวงจรชีวิตที่เรียงลำดับไว้สำหรับการรันที่ถูกสั่งงานหนึ่งครั้ง ไคลเอนต์จึงเรียงลำดับและตัดรายการซ้ำได้
- ไปป์ไลน์ — เฉพาะเหตุการณ์การรันขั้นสุดท้าย (เสร็จสมบูรณ์ ถูกยกเลิก ล้มเหลว)
- การสังเกตการณ์ — รายการบันทึกกิจกรรมและเกณฑ์งบประมาณ
- ตัวตนและสมาชิกภาพ — เพิ่มสมาชิก ลบสมาชิก เปลี่ยนบทบาท
- ปฏิทินและการประชุม — การหมดอายุของการยืนยันตัวตน การเริ่มการประชุม และการบันทึกที่สิ้นสุด
- ริก — การเข้าควบคุม การยึดคืน และการปิดโดยไม่คาดคิด
หน่วยความจำ การประสานงาน เอกสารแผน อาร์ติแฟกต์ การอนุมัติ การรับเข้าของ การซิงค์ตั๋วงาน การรีเฟรชปฏิทิน การรวม worktree การสร้างผู้ใช้ คำเชิญ และ การเพิกถอนอุปกรณ์ ไม่ใช่เหตุการณ์โดเมน ดูได้ที่หน้าอ้างอิง
สำหรับแค็ตตาล็อกฉบับสมบูรณ์ — คลาสเหตุการณ์ที่เป็นรูปธรรมทั้ง 53 คลาส เพย์โหลด ของแต่ละคลาส และผู้สมัครรับ 24 รายที่บริโภคเหตุการณ์เหล่านี้ — ดูที่ ข้อมูลอ้างอิงเหตุการณ์โดเมน หน้านั้นคือ บัญชีรายการ ส่วนหน้านี้คือโมเดล
การควบคุมการเข้าถึงแบบสดใช้กลไกสองอย่างที่ต่างกัน
หัวข้อที่มีชื่อว่า “การควบคุมการเข้าถึงแบบสดใช้กลไกสองอย่างที่ต่างกัน”เหตุการณ์สมาชิกภาพและเหตุการณ์อุปกรณ์ดูสมมาตรกัน แต่ไม่ใช่ และเรื่องนี้สำคัญ หากคุณกำลังคิดอยู่ว่าการเพิกถอนจะออกฤทธิ์เร็วเพียงใด
การเพิกถอนอุปกรณ์ยุติเซสชันของอุปกรณ์นั้นจริง เซิร์ฟเวอร์เฝ้าดูตารางอุปกรณ์ ที่จับคู่ไว้ และทิ้งเซสชันที่มีชีวิตซึ่งอุปกรณ์หลุดออกจากชุดที่ใช้งานอยู่ ภายในไม่กี่วินาที
การลบสมาชิกไม่ได้ปิดซ็อกเก็ต WorkspaceMemberRemoved ถูกบริโภค:
LocalRpcServer และ RemoteRelayHost ทิ้งการสมัครรับเวิร์กสเปซที่ผู้ใช้รายนั้น
ผูกไว้ และ RemoteEventForwarder ทำให้แคชสมาชิกภาพของตนเป็นโมฆะ เฟรมต่อๆ ไป
สำหรับเวิร์กสเปซนั้นจึงไม่ถูกส่งออกไป สิ่งที่ปฏิเสธ RPC ถัดไปยังคงเป็นด่านตรวจ
บทบาท ซึ่งแก้สมาชิกภาพใหม่ในทุกการเรียก — คำขอถัดไปของพวกเขาจึงถูกปฏิเสธ
ด้วยข้อความ “Not a member of this workspace” ผลลัพธ์เกิดขึ้นทันทีกับทุกอย่าง
ที่พวกเขาพยายามทำ เพียงแต่ไม่ได้เกิดจากการตัดสายทิ้ง
ทริกเกอร์ไปป์ไลน์
หัวข้อที่มีชื่อว่า “ทริกเกอร์ไปป์ไลน์”ทริกเกอร์ไปป์ไลน์สมัครรับเหตุการณ์โดเมนและเริ่มไปป์ไลน์ที่ตรงกันโดยอัตโนมัติ
PipelineTriggerDispatcher ฟังทั้งบัส แล้ว:
- ตัดจบก่อน เว้นแต่ชนิดของเหตุการณ์จะเป็นชนิดที่รู้วิธีแมปไปยังเพย์โหลด
- ค้นหาทริกเกอร์ที่เปิดใช้งานซึ่งตรงกับชนิดเหตุการณ์นั้น ทั่วทุกเวิร์กสเปซ
- กรองแต่ละตัวให้เหลือเวิร์กสเปซของตัวเองและใช้ตัวกรองการจับคู่เพย์โหลดของมัน
- เริ่มการรันสำหรับทริกเกอร์แต่ละตัวที่รอดมา
ข้อจำกัดสำคัญคือข้อ 1 บัสพกชนิดเหตุการณ์ 53 ชนิด ตัวเลือกการเพิ่มทริกเกอร์
เริ่มการรันสำหรับสิบสี่ชนิดนี้ (สาขาเพย์โหลดของ EventPayloadMapper):
ExternalPrDetected, PullRequestPublished, PullRequestStatusChanged,
PrMerged, MessageReceived, TicketAssigned,
TicketCompleted, TicketFailed, TicketCancelled,
BudgetThresholdCrossed, RepoAdded, MeetingRecordingStopped, SkillUpdated
และ SpaceDeleted ไม่มีชนิดอื่นที่เริ่มไปป์ไลน์ได้
ไคลเอนต์มองเห็นเรื่องเหล่านี้ได้อย่างไร
หัวข้อที่มีชื่อว่า “ไคลเอนต์มองเห็นเรื่องเหล่านี้ได้อย่างไร”RemoteEventForwarder แปลเหตุการณ์ประเภทการแจ้งเตือนเป็นเฟรมบนสายและส่งผ่าน
RPC ไปยังเซสชันที่เชื่อมต่ออยู่ ซึ่งตัวแมปเฟรมจะเปลี่ยนเฟรมเหล่านั้นเป็น
การแจ้งเตือนในแอป ไคลเอนต์แบบบางจึงเห็นภาพฉายของสตรีมเหตุการณ์ของเซิร์ฟเวอร์
โดยไม่ได้เป็นเจ้าของการทำงานใดๆ — ซึ่งนั่นคือประเด็นทั้งหมดของ
การแยกไคลเอนต์แบบบาง
แต่ไม่ใช่ทุกเฟรมที่ถูกส่งมาเป็นการแจ้งเตือน สตรีมวงจรชีวิตของงานและ การมอบหมายตั๋วงานใหม่ถูกส่งต่อแบบสดเพื่อขับเคลื่อน UI แต่จะไม่ถูกบันทึกลง ฟีดการแจ้งเตือนและไม่เด้งการแจ้งเตือนใดๆ
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- ไปป์ไลน์และระบบอัตโนมัติ: สิ่งที่ทริกเกอร์เริ่ม
- ตั๋วงานและการมอบหมาย: การมอบหมายให้เอเจนต์เทียบกับทีม
- สถาปัตยกรรม: เหตุการณ์เข้ากับกฎการพึ่งพาอย่างไร
- ข้อมูลอ้างอิงเหตุการณ์โดเมน: แค็ตตาล็อกฉบับสมบูรณ์และผู้สมัครรับของมัน
- ตั้งทริกเกอร์ไปป์ไลน์
- ตั้งค่าการแจ้งเตือน