From 4c5e7eb91753e69a77da0136f607683e17ae822f Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 31 May 2026 23:53:04 -0400 Subject: [PATCH] docs(spike): inline Mermaid for store-and-forward lifecycle Swap the store-and-forward Message Lifecycle PNG embed for an inline mermaid block to verify whether gitea renders mermaid in markdown. If it does, the standard flow/state/hierarchy diagrams can move to inline mermaid (text-only, auto-layout) instead of draw.io source + PNG. --- .../requirements/Component-StoreAndForward.md | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/requirements/Component-StoreAndForward.md b/docs/requirements/Component-StoreAndForward.md index 4b6fa379..3396fa57 100644 --- a/docs/requirements/Component-StoreAndForward.md +++ b/docs/requirements/Component-StoreAndForward.md @@ -25,8 +25,28 @@ Site clusters only. The central cluster does not buffer messages. ## Message Lifecycle -![storeforward-message-lifecycle](diagrams/storeforward-message-lifecycle.png) - +```mermaid +flowchart TD + A([Script submits message]) --> B[Attempt immediate delivery] + B --> C{Delivered?} + C -->|Success| D([Remove from buffer]) + C -->|Failure| E[Buffer message] + E --> F[Retry loop
per retry policy] + F --> G{Retry outcome} + G -->|Success| H([Remove from buffer
+ notify standby]) + G -->|Max retries exhausted| I([Park message
dead-letter]) + + classDef ok fill:#d5e8d4,stroke:#82b366; + classDef proc fill:#dae8fc,stroke:#6c8ebf; + classDef dec fill:#fff2cc,stroke:#d6b656; + classDef buf fill:#ffe6cc,stroke:#d79b00; + classDef bad fill:#f8cecc,stroke:#b85450; + class A,D,H ok + class B,F proc + class C,G dec + class E buf + class I bad +``` For notifications, "delivery" means forwarding the message to the central cluster via Central–Site Communication; "success" is central's ack, on which the message is cleared. Notifications are retried at the fixed forward interval until central acks, but — like every other category — they are bounded by the engine's `DefaultMaxRetries` cap: a sustained central outage that exceeds `DefaultMaxRetries × forward-interval` will park the buffered notification, after which an operator can Retry/Discard it via the parked-message UI. Operationally, the cap is sized so the normal central-recovery window stays well inside it; "do not park" is the design's operational intent on the happy path, not an absolute invariant. Callers that genuinely require unbounded retry pass `maxRetries: 0` on `EnqueueAsync` (the documented "no limit" escape hatch — see `StoreAndForward-015`).