mirror of https://github.com/abpframework/abp.git
csharpabpc-sharpframeworkblazoraspnet-coredotnet-coreaspnetcorearchitecturesaasdomain-driven-designangularmulti-tenancy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
7.8 KiB
141 lines
7.8 KiB
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 600">
|
|
<defs>
|
|
<style>
|
|
.box { fill: #f8f9fa; stroke: #1890ff; stroke-width: 2; }
|
|
.db-box { fill: #fff7e6; stroke: #fa8c16; stroke-width: 2; }
|
|
.cache-box { fill: #f0f5ff; stroke: #597ef7; stroke-width: 2; }
|
|
.event-box { fill: #f6ffed; stroke: #52c41a; stroke-width: 2; }
|
|
.invalidate-box { fill: #fff1f0; stroke: #ff4d4f; stroke-width: 2; }
|
|
.text { font-family: Arial, sans-serif; font-size: 14px; fill: #333; }
|
|
.title { font-family: Arial, sans-serif; font-size: 18px; fill: #1890ff; font-weight: bold; }
|
|
.section-title { font-family: Arial, sans-serif; font-size: 14px; fill: #1890ff; font-weight: bold; }
|
|
.small-text { font-family: Arial, sans-serif; font-size: 11px; fill: #666; }
|
|
.arrow { stroke: #666; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
|
|
.event-arrow { stroke: #52c41a; stroke-width: 2; fill: none; marker-end: url(#arrowhead-green); }
|
|
.invalidate-arrow { stroke: #ff4d4f; stroke-width: 3; fill: none; marker-end: url(#arrowhead-red); }
|
|
.step-number { fill: #1890ff; font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; }
|
|
</style>
|
|
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
<polygon points="0 0, 10 3, 0 6" fill="#666" />
|
|
</marker>
|
|
<marker id="arrowhead-green" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
<polygon points="0 0, 10 3, 0 6" fill="#52c41a" />
|
|
</marker>
|
|
<marker id="arrowhead-red" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
<polygon points="0 0, 10 3, 0 6" fill="#ff4d4f" />
|
|
</marker>
|
|
</defs>
|
|
|
|
<!-- Title -->
|
|
<text class="title" x="500" y="35" text-anchor="middle">Cache Invalidation Workflow</text>
|
|
|
|
<!-- Step 1: User Action -->
|
|
<circle cx="100" cy="100" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="100" y="107" text-anchor="middle" fill="white">1</text>
|
|
|
|
<rect class="box" x="150" y="70" width="180" height="60" rx="5" />
|
|
<text class="text" x="240" y="95" text-anchor="middle">User Action</text>
|
|
<text class="small-text" x="240" y="115" text-anchor="middle">UpdateAsync(bookId)</text>
|
|
|
|
<!-- Step 2: Database Update -->
|
|
<circle cx="100" cy="220" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="100" y="227" text-anchor="middle" fill="white">2</text>
|
|
|
|
<rect class="db-box" x="150" y="190" width="180" height="60" rx="5" />
|
|
<text class="text" x="240" y="215" text-anchor="middle">Update Database</text>
|
|
<text class="small-text" x="240" y="235" text-anchor="middle">Repository.UpdateAsync()</text>
|
|
|
|
<!-- Step 3: Publish Event -->
|
|
<circle cx="100" cy="340" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="100" y="347" text-anchor="middle" fill="white">3</text>
|
|
|
|
<rect class="event-box" x="150" y="310" width="180" height="60" rx="5" />
|
|
<text class="text" x="240" y="335" text-anchor="middle">Publish Event</text>
|
|
<text class="small-text" x="240" y="355" text-anchor="middle">EntityChangedEvent</text>
|
|
|
|
<!-- Arrows for steps 1-3 -->
|
|
<path class="arrow" d="M 240 130 L 240 190" />
|
|
<path class="arrow" d="M 240 250 L 240 310" />
|
|
|
|
<!-- Step 4: Event Handler -->
|
|
<circle cx="500" cy="340" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="500" y="347" text-anchor="middle" fill="white">4</text>
|
|
|
|
<rect class="event-box" x="550" y="310" width="200" height="60" rx="5" />
|
|
<text class="text" x="650" y="330" text-anchor="middle">Invalidation</text>
|
|
<text class="text" x="650" y="348" text-anchor="middle">Handler</text>
|
|
<text class="small-text" x="650" y="363" text-anchor="middle">Listen for changes</text>
|
|
|
|
<!-- Arrow to handler -->
|
|
<path class="event-arrow" d="M 330 340 L 550 340" />
|
|
<text class="small-text" x="400" y="330" fill="#52c41a">Event Bus</text>
|
|
|
|
<!-- Step 5: UnitOfWork Check -->
|
|
<circle cx="500" cy="460" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="500" y="467" text-anchor="middle" fill="white">5</text>
|
|
|
|
<rect class="box" x="550" y="430" width="200" height="60" rx="5" />
|
|
<text class="text" x="650" y="455" text-anchor="middle">Wait for UoW</text>
|
|
<text class="small-text" x="650" y="475" text-anchor="middle">OnCompleted() callback</text>
|
|
|
|
<!-- Arrow to UoW -->
|
|
<path class="arrow" d="M 650 370 L 650 430" />
|
|
|
|
<!-- Step 6: Clear Cache -->
|
|
<circle cx="850" cy="340" r="20" fill="#1890ff" />
|
|
<text class="step-number" x="850" y="347" text-anchor="middle" fill="white">6</text>
|
|
|
|
<rect class="invalidate-box" x="790" y="310" width="160" height="120" rx="5" />
|
|
<text class="text" x="870" y="335" text-anchor="middle">Clear Cache</text>
|
|
|
|
<!-- Cache entries being cleared -->
|
|
<line x1="805" y1="355" x2="935" y2="355" stroke="#ff4d4f" stroke-width="1" opacity="0.3"/>
|
|
<text class="small-text" x="815" y="375" fill="#ff4d4f">✗ GetAsync(id)</text>
|
|
<text class="small-text" x="815" y="392" fill="#ff4d4f">✗ GetListAsync()</text>
|
|
<text class="small-text" x="815" y="409" fill="#ff4d4f">✗ Related queries</text>
|
|
|
|
<!-- Arrow to clear cache -->
|
|
<path class="invalidate-arrow" d="M 750 460 L 870 460 L 870 430" />
|
|
<text class="small-text" x="785" y="452" fill="#ff4d4f" font-weight="bold">INVALIDATE</text>
|
|
|
|
<!-- Cache Storage Visualization -->
|
|
<rect class="cache-box" x="50" y="500" width="900" height="80" rx="5" />
|
|
<text class="section-title" x="500" y="525" text-anchor="middle">Redis / Distributed Cache</text>
|
|
|
|
<!-- Before invalidation -->
|
|
<text class="small-text" x="70" y="550" font-weight="bold">Before:</text>
|
|
<rect x="130" y="540" width="120" height="25" fill="#52c41a" opacity="0.3" rx="2" stroke="#52c41a"/>
|
|
<text class="small-text" x="190" y="557" text-anchor="middle">Book:Get:123 ✓</text>
|
|
|
|
<rect x="260" y="540" width="120" height="25" fill="#52c41a" opacity="0.3" rx="2" stroke="#52c41a"/>
|
|
<text class="small-text" x="320" y="557" text-anchor="middle">Book:List ✓</text>
|
|
|
|
<!-- After invalidation -->
|
|
<text class="small-text" x="560" y="550" font-weight="bold">After:</text>
|
|
<rect x="620" y="540" width="120" height="25" fill="#ff4d4f" opacity="0.2" rx="2" stroke="#ff4d4f" stroke-dasharray="3,3"/>
|
|
<text class="small-text" x="680" y="557" text-anchor="middle" fill="#999" text-decoration="line-through">Book:Get:123</text>
|
|
|
|
<rect x="750" y="540" width="120" height="25" fill="#ff4d4f" opacity="0.2" rx="2" stroke="#ff4d4f" stroke-dasharray="3,3"/>
|
|
<text class="small-text" x="810" y="557" text-anchor="middle" fill="#999" text-decoration="line-through">Book:List</text>
|
|
|
|
<!-- Arrow showing invalidation -->
|
|
<path class="invalidate-arrow" d="M 400 552 L 600 552" />
|
|
<text class="small-text" x="475" y="545" fill="#ff4d4f" font-weight="bold">CLEARED</text>
|
|
|
|
<!-- Timeline -->
|
|
<line x1="50" y1="100" x2="50" y2="490" stroke="#1890ff" stroke-width="2" opacity="0.3"/>
|
|
<text class="small-text" x="15" y="105" fill="#1890ff" transform="rotate(-90, 15, 105)">Timeline</text>
|
|
|
|
<!-- Info boxes -->
|
|
<rect x="400" y="70" width="250" height="100" rx="5" fill="#f0f5ff" stroke="#597ef7" stroke-width="2"/>
|
|
<text class="section-title" x="525" y="95" text-anchor="middle">Why Wait for UoW?</text>
|
|
<text class="small-text" x="415" y="115">• Ensures transaction completes</text>
|
|
<text class="small-text" x="415" y="132">• Prevents cache-DB inconsistency</text>
|
|
<text class="small-text" x="415" y="149">• Handles rollback scenarios</text>
|
|
|
|
<rect x="700" y="70" width="250" height="100" rx="5" fill="#fff1f0" stroke="#ff4d4f" stroke-width="2"/>
|
|
<text class="section-title" x="825" y="95" text-anchor="middle">Invalidation Scope</text>
|
|
<text class="small-text" x="715" y="115">• All caches with [Cache(Book)]</text>
|
|
<text class="small-text" x="715" y="132">• Across all scopes (Global, User)</text>
|
|
<text class="small-text" x="715" y="149">• Entity-specific keys by ID</text>
|
|
</svg>
|