docs: convert standard diagrams from draw.io PNGs to inline Mermaid

Gitea renders mermaid inline, so the flow/state/hierarchy/DAG diagrams
move to text-in-markdown: auto-layout (removes the manual overlap-prone
draw.io step), diffable source, no committed binaries, and a dark-text
theme so labels stay legible. Keep draw.io PNGs only for the two complex
bespoke diagrams (logical architecture, env2 topology) where pixel
control still wins. All 24 mermaid blocks validated by rendering.
This commit is contained in:
Joseph Doherty
2026-06-01 00:23:00 -04:00
parent e3ca5ac0cf
commit 43228185b4
65 changed files with 848 additions and 2145 deletions
+77 -6
View File
@@ -23,8 +23,39 @@ gRPC server-streaming is an established pattern for real-time tag value updates;
## Architecture
![grpc-streams-architecture](diagrams/grpc-streams-architecture.png)
<!-- source: diagrams/grpc-streams-architecture.drawio — edit, then re-export with export-drawio.sh -->
```mermaid
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
flowchart TD
subgraph CENTRAL["Central Cluster"]
BT["DebugStreamBridgeActor"]
GC["SiteStreamGrpcClient<br/>(per-site, on central)"]
BB["DebugStreamBridgeActor"]
SR(["SignalR Hub / Blazor UI"])
end
subgraph SITE["Site Cluster"]
IN["InstanceActor"]
PB{"publishes<br/>AttributeValueChanged<br/>AlarmStateChanged"}
GS["SiteStreamGrpcServer<br/>(Kestrel, on site)"]
end
BT -.->|"SubscribeDebugView"| IN
IN -.->|"DebugViewSnapshot"| BT
IN --> PB
PB --> GS
GS -->|"gRPC stream (HTTP/2)"| GC
GC --> BB
BB --> SR
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
class BT,GC,BB proc
class SR start
class IN,GS warn
class PB dec
```
**Key separation**: ClusterClient handles subscribe/unsubscribe/snapshot (request-response). gRPC handles the ongoing value stream (server-streaming).
@@ -250,8 +281,23 @@ public override async Task SubscribeInstance(
`IServerStreamWriter<T>` is **not thread-safe**. Multiple Akka actors may publish events concurrently. The `Channel<SiteStreamEvent>` bridges these worlds:
![grpc-channel-bridging](diagrams/grpc-channel-bridging.png)
<!-- source: diagrams/grpc-channel-bridging.drawio — edit, then re-export with export-drawio.sh -->
```mermaid
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
flowchart TD
AKKA["Akka Actor Thread(s)"]
CH(["Channel&lt;SiteStreamEvent&gt;<br/><br/>BoundedChannelOptions(1000)<br/>FullMode = DropOldest"])
GRPC["gRPC Response Stream"]
AKKA -->|"channel.Writer.TryWrite(evt)"| CH
CH -->|"await responseStream.WriteAsync(evt)"| GRPC
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
class AKKA warn
class CH start
class GRPC proc
```
- **Bounded capacity** (1000): prevents unbounded memory growth if the gRPC client is slow
- **DropOldest**: matches the existing `SiteStreamManager` overflow strategy
@@ -401,8 +447,33 @@ private void HandleGrpcStreamError(Exception ex)
### Reconnection State Machine (DebugStreamBridgeActor)
![grpc-reconnection-state-machine](diagrams/grpc-reconnection-state-machine.png)
<!-- source: diagrams/grpc-reconnection-state-machine.drawio — edit, then re-export with export-drawio.sh -->
```mermaid
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
flowchart TD
S(["Streaming<br/><i>Normal state: gRPC stream active</i>"])
R(["Reconnecting<br/><i>try other node endpoint</i>"])
D{"reconnect result?"}
RT["schedule retry<br/>(5s backoff)"]
T(["Terminated<br/><i>notify consumer, stop actor</i>"])
S -->|"gRPC stream error / keepalive timeout"| R
R --> D
D -->|"success"| S
D -->|"failure (retry &lt; max)"| RT
RT --> R
D -->|"failure (retry &gt;= max)"| T
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
classDef bad fill:#f8cecc,stroke:#b85450,color:#111111;
class S start
class R dec
class D proc
class RT warn
class T bad
```
### Summary