update agent diagram

This commit is contained in:
Evgeny @ SimpleX Chat
2026-03-14 15:35:53 +00:00
parent 8e294cb72d
commit 7410cebac5
2 changed files with 239 additions and 143 deletions
+52
View File
@@ -131,3 +131,55 @@ sequenceDiagram
SMP->>AB: MSG (HELLO)
AB->>B: CON (connected)
```
### File delivery flow (XFTP)
```mermaid
sequenceDiagram
participant SA as Sender App
box Sender Agent
participant S as xftpSnd workers
participant SS as Store
end
participant XFTP as XFTP Routers
participant SMP as SMP Router
box Receiver Agent
participant RS as Store
participant R as xftpRcv workers
end
participant RA as Receiver App
SA->>S: xftpSendFile(file)
S->>S: encrypt file<br>(XSalsa20-Poly1305, random key + nonce)
S->>S: split into chunks<br>(fixed sizes: 64KB - 4MB)
S->>SS: store SndFile + chunks
loop each chunk
S->>XFTP: FNEW (create data packet)
XFTP->>S: sender ID + recipient IDs
S->>XFTP: FPUT (upload encrypted chunk)
end
S->>S: assemble FileDescription<br>(chunk locations, replicas,<br>encryption key + nonce)
S->>SA: SFDONE<br>(sender + recipient descriptions)
Note over SA,RA: recipient description sent as<br>SMP message (encrypted, via double ratchet)
SA->>SMP: description in A_MSG
SMP->>RA: description in MSG
RA->>R: xftpReceiveFile(description)
R->>RS: store RcvFile + chunks
loop each chunk (parallel per server)
R->>XFTP: FGET (per-recipient auth key)
XFTP->>R: encrypted chunk stream
end
R->>R: stream chunks through<br>stateful decrypt (key + nonce),<br>verify auth tag at end
R->>RA: RFDONE (decrypted file path)
```
+187 -143
View File
@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 560" font-family="monospace" font-size="12">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 555" font-family="monospace" font-size="12">
<defs>
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
@@ -8,195 +8,239 @@
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#999" />
</marker>
<marker id="arr-x" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#c62828" />
</marker>
</defs>
<!-- ===== APPLICATION (external) ===== -->
<rect x="350" y="10" width="260" height="34" rx="4"
<!-- ===== ROW 0: APPLICATION (external) ===== -->
<rect x="370" y="10" width="220" height="32" rx="4"
fill="#fce8e6" stroke="#ea4335" />
<text x="480" y="32" text-anchor="middle">Application</text>
<text x="480" y="31" text-anchor="middle">Application</text>
<!-- ===== subQ: subscriber -> Application ===== -->
<polyline points="114,78 114,27 348,27"
<!-- ===== App -> API arrows (down) ===== -->
<line x1="420" y1="42" x2="170" y2="56"
stroke="#999" marker-end="url(#arr-g)" />
<line x1="480" y1="42" x2="480" y2="56"
stroke="#999" marker-end="url(#arr-g)" />
<line x1="540" y1="42" x2="786" y2="56"
stroke="#999" marker-end="url(#arr-g)" />
<!-- ===== subQ: columns -> Application ===== -->
<polyline points="480,302 480,290 945,290 945,26 592,26"
fill="none" stroke="#333" marker-end="url(#arr)" />
<text x="128" y="58" font-size="10" fill="#555">subQ</text>
<text x="930" y="160" font-size="10" fill="#555">subQ</text>
<!-- ===== MAIN THREADS GROUP ===== -->
<rect x="20" y="56" width="920" height="88" rx="6"
<!-- ===== ROW 1: API FUNCTIONS ===== -->
<!-- SMP API -->
<rect x="25" y="56" width="290" height="44" rx="4"
fill="#f4f4f4" stroke="#999" />
<text x="170" y="73" text-anchor="middle" font-size="10">sendMessage, createConnection</text>
<text x="170" y="87" text-anchor="middle" font-size="10">joinConnection, subscribe...</text>
<!-- XFTP API -->
<rect x="333" y="56" width="290" height="44" rx="4"
fill="#f4f4f4" stroke="#999" />
<text x="478" y="73" text-anchor="middle" font-size="10">xftpSendFile</text>
<text x="478" y="87" text-anchor="middle" font-size="10">xftpReceiveFile...</text>
<!-- NTF API -->
<rect x="641" y="56" width="290" height="44" rx="4"
fill="#f4f4f4" stroke="#999" />
<text x="786" y="73" text-anchor="middle" font-size="10">registerNtfToken</text>
<text x="786" y="87" text-anchor="middle" font-size="10">toggleConnectionNtfs...</text>
<!-- ===== ROW 2: THREE PROTOCOL COLUMNS ===== -->
<!-- SMP column outline -->
<rect x="20" y="112" width="305" height="190" rx="6"
fill="none" stroke="#888" stroke-dasharray="6,3" />
<text x="30" y="69" fill="#888" font-size="10">main threads (raceAny_: any exit tears down all)</text>
<text x="30" y="125" fill="#888" font-size="10">SMP</text>
<!-- subscriber -->
<rect x="40" y="78" width="148" height="46" rx="4"
<!-- subscriber (green, singleton) -->
<rect x="35" y="134" width="145" height="40" rx="4"
fill="#e6f4ea" stroke="#34a853" />
<text x="114" y="98" text-anchor="middle">subscriber</text>
<text x="114" y="112" text-anchor="middle" font-size="9" fill="#666">(reads msgQ)</text>
<text x="107" y="152" text-anchor="middle">subscriber</text>
<text x="107" y="166" text-anchor="middle" font-size="9" fill="#666">(reads msgQ)</text>
<!-- ntfSubQ label + arrow -->
<text x="222" y="98" font-size="10" fill="#555" text-anchor="end">ntfSubQ</text>
<line x1="228" y1="101" x2="278" y2="101"
<!-- delivery worker -->
<rect x="35" y="188" width="128" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="99" y="204" text-anchor="middle" font-size="11">delivery</text>
<text x="99" y="216" text-anchor="middle" font-size="8" fill="#666">(per send queue)</text>
<!-- asyncCmd worker -->
<rect x="175" y="188" width="135" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="242" y="204" text-anchor="middle" font-size="11">asyncCmd</text>
<text x="242" y="216" text-anchor="middle" font-size="8" fill="#666">(per connection)</text>
<!-- smpSub worker -->
<rect x="35" y="236" width="128" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="99" y="252" text-anchor="middle" font-size="11">smpSub</text>
<text x="99" y="264" text-anchor="middle" font-size="8" fill="#666">(per session)</text>
<!-- XFTP column outline -->
<rect x="333" y="112" width="300" height="190" rx="6"
fill="none" stroke="#888" stroke-dasharray="6,3" />
<text x="343" y="125" fill="#888" font-size="10">XFTP</text>
<!-- xftpRcv worker -->
<rect x="348" y="188" width="130" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="413" y="204" text-anchor="middle" font-size="11">xftpRcv</text>
<text x="413" y="216" text-anchor="middle" font-size="8" fill="#666">(per server + local)</text>
<!-- xftpSnd worker -->
<rect x="490" y="188" width="130" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="555" y="204" text-anchor="middle" font-size="11">xftpSnd</text>
<text x="555" y="216" text-anchor="middle" font-size="8" fill="#666">(per server + local)</text>
<!-- xftpDel worker -->
<rect x="348" y="236" width="130" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="413" y="252" text-anchor="middle" font-size="11">xftpDel</text>
<text x="413" y="264" text-anchor="middle" font-size="8" fill="#666">(per server)</text>
<!-- NTF column outline -->
<rect x="641" y="112" width="295" height="190" rx="6"
fill="none" stroke="#888" stroke-dasharray="6,3" />
<text x="651" y="125" fill="#888" font-size="10">NTF</text>
<!-- ntfSupervisor (green, singleton) -->
<rect x="656" y="134" width="165" height="40" rx="4"
fill="#e6f4ea" stroke="#34a853" />
<text x="738" y="152" text-anchor="middle">ntfSupervisor</text>
<text x="738" y="166" text-anchor="middle" font-size="9" fill="#666">(reads ntfSubQ)</text>
<!-- ntfWorkers -->
<rect x="656" y="188" width="125" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="718" y="204" text-anchor="middle" font-size="11">ntfWorkers</text>
<text x="718" y="216" text-anchor="middle" font-size="8" fill="#666">(per NTF server)</text>
<!-- ntfSMP worker -->
<rect x="793" y="188" width="128" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="857" y="204" text-anchor="middle" font-size="11">ntfSMP</text>
<text x="857" y="216" text-anchor="middle" font-size="8" fill="#666">(per SMP server)</text>
<!-- ntfTknDel worker -->
<rect x="656" y="236" width="125" height="34" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="718" y="252" text-anchor="middle" font-size="11">ntfTknDel</text>
<text x="718" y="264" text-anchor="middle" font-size="8" fill="#666">(per NTF server)</text>
<!-- ===== ntfSubQ: NTF API -> ntfSupervisor ===== -->
<line x1="786" y1="100" x2="738" y2="132"
stroke="#333" marker-end="url(#arr)" />
<text x="775" y="120" font-size="10" fill="#555">ntfSubQ</text>
<!-- ntfSupervisor -->
<rect x="280" y="78" width="168" height="46" rx="4"
<!-- ===== CROSS-PROTOCOL: asyncCmd -> ntfSubQ (ICQDelete) ===== -->
<polyline points="310,200 486,155 656,155"
fill="none" stroke="#c62828" stroke-dasharray="4,3" marker-end="url(#arr-x)" />
<text x="420" y="146" font-size="9" fill="#c62828">ntfSubQ (queue rotation)</text>
<!-- ===== CROSS-PROTOCOL: ntfSMP -> smpClients ===== -->
<polyline points="857,222 857,340 170,340 170,398"
fill="none" stroke="#c62828" stroke-dasharray="4,3" marker-end="url(#arr-x)" />
<text x="500" y="336" font-size="9" fill="#c62828">ntfSMP uses smpClients</text>
<!-- ===== SHARED SINGLETON THREADS ===== -->
<rect x="200" y="310" width="130" height="22" rx="4"
fill="#e6f4ea" stroke="#34a853" />
<text x="364" y="98" text-anchor="middle">ntfSupervisor</text>
<text x="364" y="112" text-anchor="middle" font-size="9" fill="#666">(reads ntfSubQ)</text>
<text x="265" y="325" text-anchor="middle" font-size="10">cleanupManager</text>
<!-- cleanupManager -->
<rect x="540" y="78" width="168" height="46" rx="4"
<rect x="345" y="310" width="130" height="22" rx="4"
fill="#e6f4ea" stroke="#34a853" />
<text x="624" y="98" text-anchor="middle">cleanupManager</text>
<text x="624" y="112" text-anchor="middle" font-size="9" fill="#666">(periodic cleanup)</text>
<text x="410" y="325" text-anchor="middle" font-size="10">logServersStats</text>
<!-- logServersStats -->
<rect x="760" y="78" width="165" height="46" rx="4"
fill="#e6f4ea" stroke="#34a853" />
<text x="842" y="98" text-anchor="middle">logServersStats</text>
<text x="842" y="112" text-anchor="middle" font-size="9" fill="#666">(periodic stats)</text>
<text x="30" y="325" fill="#888" font-size="9">shared singletons (all green run in raceAny_)</text>
<!-- ===== WORKER POOLS GROUP ===== -->
<rect x="20" y="155" width="920" height="148" rx="6"
fill="none" stroke="#888" stroke-dasharray="6,3" />
<text x="30" y="168" fill="#888" font-size="10">worker pools (on-demand, one per queue/connection/server)</text>
<!-- ===== ROW 3: CENTRAL STATE ===== -->
<rect x="25" y="346" width="450" height="42" rx="4"
fill="#fef7e0" stroke="#f9ab00" />
<text x="250" y="366" text-anchor="middle" font-weight="bold">Store</text>
<text x="250" y="380" text-anchor="middle" font-size="10">(SQLite / Postgres)</text>
<!-- Sub-row A: SMP workers -->
<rect x="40" y="180" width="120" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="100" y="196" text-anchor="middle" font-size="11">delivery</text>
<text x="100" y="209" text-anchor="middle" font-size="8" fill="#666">(per send queue)</text>
<rect x="490" y="346" width="445" height="42" rx="4"
fill="#fef7e0" stroke="#f9ab00" />
<text x="712" y="366" text-anchor="middle" font-weight="bold">Operation State</text>
<text x="712" y="380" text-anchor="middle" font-size="10">(5-op suspension cascade)</text>
<rect x="170" y="180" width="115" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="227" y="196" text-anchor="middle" font-size="11">asyncCmd</text>
<text x="227" y="209" text-anchor="middle" font-size="8" fill="#666">(per connection)</text>
<rect x="295" y="180" width="98" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="344" y="196" text-anchor="middle" font-size="11">smpSub</text>
<text x="344" y="209" text-anchor="middle" font-size="8" fill="#666">(per session)</text>
<!-- Sub-row A: XFTP workers -->
<rect x="435" y="180" width="92" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="481" y="196" text-anchor="middle" font-size="11">xftpRcv</text>
<text x="481" y="209" text-anchor="middle" font-size="8" fill="#666">(per server)</text>
<rect x="537" y="180" width="92" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="583" y="196" text-anchor="middle" font-size="11">xftpSnd</text>
<text x="583" y="209" text-anchor="middle" font-size="8" fill="#666">(per server)</text>
<rect x="639" y="180" width="92" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="685" y="196" text-anchor="middle" font-size="11">xftpDel</text>
<text x="685" y="209" text-anchor="middle" font-size="8" fill="#666">(per server)</text>
<!-- Sub-row B: NTF workers (split by protocol client column) -->
<rect x="40" y="234" width="120" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="100" y="250" text-anchor="middle" font-size="11">ntfSMP</text>
<text x="100" y="263" text-anchor="middle" font-size="8" fill="#666">(per SMP server)</text>
<rect x="639" y="234" width="115" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="696" y="250" text-anchor="middle" font-size="11">ntfWorkers</text>
<text x="696" y="263" text-anchor="middle" font-size="8" fill="#666">(per NTF server)</text>
<rect x="764" y="234" width="120" height="36" rx="4"
fill="#e8f0fe" stroke="#4285f4" />
<text x="824" y="250" text-anchor="middle" font-size="11">ntfTknDel</text>
<text x="824" y="263" text-anchor="middle" font-size="8" fill="#666">(per NTF server)</text>
<!-- ntf dispatch note -->
<text x="415" y="257" text-anchor="middle" font-size="9" fill="#888">
ntf workers (dispatched by ntfSupervisor)
</text>
<!-- ntfSupervisor dispatch arrow: through gap at x=415 -->
<line x1="415" y1="124" x2="415" y2="240"
stroke="#888" stroke-dasharray="3,2" marker-end="url(#arr-g)" />
<!-- store access: representative dashed line from asyncCmd to Store -->
<line x1="227" y1="216" x2="200" y2="318"
<!-- store access: representative dashed line -->
<line x1="242" y1="222" x2="200" y2="344"
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
<text x="225" y="272" font-size="9" fill="#555">store</text>
<text x="233" y="288" font-size="9" fill="#555">store</text>
<!-- ===== CENTRAL STATE ===== -->
<rect x="40" y="318" width="280" height="48" rx="4"
fill="#fef7e0" stroke="#f9ab00" />
<text x="180" y="338" text-anchor="middle" font-weight="bold">Store</text>
<text x="180" y="354" text-anchor="middle" font-size="10">(SQLite / Postgres)</text>
<rect x="345" y="318" width="250" height="48" rx="4"
fill="#fef7e0" stroke="#f9ab00" />
<text x="470" y="338" text-anchor="middle" font-weight="bold">currentSubs</text>
<text x="470" y="354" text-anchor="middle" font-size="10">(TSessionSubs)</text>
<rect x="620" y="318" width="280" height="48" rx="4"
fill="#fef7e0" stroke="#f9ab00" />
<text x="760" y="338" text-anchor="middle" font-weight="bold">Operation State</text>
<text x="760" y="354" text-anchor="middle" font-size="10">(5-op suspension cascade)</text>
<!-- ===== PROTOCOL CLIENT POOLS ===== -->
<rect x="20" y="382" width="920" height="80" rx="6"
fill="none" stroke="#888" stroke-dasharray="6,3" />
<text x="30" y="395" fill="#888" font-size="10">protocol client pools (lazy singleton per router)</text>
<rect x="40" y="404" width="270" height="46" rx="4"
<!-- ===== ROW 4: PROTOCOL CLIENT POOLS ===== -->
<rect x="25" y="398" width="290" height="42" rx="4"
fill="#fce8e6" stroke="#ea4335" />
<text x="175" y="424" text-anchor="middle">smpClients</text>
<text x="175" y="438" text-anchor="middle" font-size="9" fill="#666">(TMap SMPTransportSession)</text>
<text x="170" y="418" text-anchor="middle">smpClients</text>
<text x="170" y="432" text-anchor="middle" font-size="9" fill="#666">(TMap SMPTransportSession)</text>
<rect x="340" y="404" width="270" height="46" rx="4"
<rect x="333" y="398" width="290" height="42" rx="4"
fill="#fce8e6" stroke="#ea4335" />
<text x="475" y="424" text-anchor="middle">xftpClients</text>
<text x="475" y="438" text-anchor="middle" font-size="9" fill="#666">(TMap XFTPTransportSession)</text>
<text x="478" y="418" text-anchor="middle">xftpClients</text>
<text x="478" y="432" text-anchor="middle" font-size="9" fill="#666">(TMap XFTPTransportSession)</text>
<rect x="640" y="404" width="270" height="46" rx="4"
<rect x="641" y="398" width="290" height="42" rx="4"
fill="#fce8e6" stroke="#ea4335" />
<text x="775" y="424" text-anchor="middle">ntfClients</text>
<text x="775" y="438" text-anchor="middle" font-size="9" fill="#666">(TMap NtfTransportSession)</text>
<text x="786" y="418" text-anchor="middle">ntfClients</text>
<text x="786" y="432" text-anchor="middle" font-size="9" fill="#666">(TMap NtfTransportSession)</text>
<!-- ===== EXTERNAL ROUTERS ===== -->
<text x="175" y="478" text-anchor="middle" font-size="9" fill="#999">SMP Routers</text>
<line x1="175" y1="450" x2="175" y2="468"
<!-- ===== ROW 5: EXTERNAL ROUTERS ===== -->
<text x="170" y="468" text-anchor="middle" font-size="9" fill="#999">SMP Routers</text>
<line x1="170" y1="440" x2="170" y2="458"
stroke="#999" marker-end="url(#arr-g)" />
<text x="475" y="478" text-anchor="middle" font-size="9" fill="#999">XFTP Routers</text>
<line x1="475" y1="450" x2="475" y2="468"
<text x="478" y="468" text-anchor="middle" font-size="9" fill="#999">XFTP Routers</text>
<line x1="478" y1="440" x2="478" y2="458"
stroke="#999" marker-end="url(#arr-g)" />
<text x="775" y="478" text-anchor="middle" font-size="9" fill="#999">NTF Routers</text>
<line x1="775" y1="450" x2="775" y2="468"
<text x="786" y="468" text-anchor="middle" font-size="9" fill="#999">NTF Routers</text>
<line x1="786" y1="440" x2="786" y2="458"
stroke="#999" marker-end="url(#arr-g)" />
<!-- ===== msgQ: smpClients -> subscriber (left margin) ===== -->
<polyline points="40,427 15,427 15,101 38,101"
<polyline points="25,419 10,419 10,154 33,154"
fill="none" stroke="#333" marker-end="url(#arr)" />
<text x="7" y="118" font-size="10" fill="#555">msgQ</text>
<text x="3" y="170" font-size="10" fill="#555">msgQ</text>
<!-- ===== LEGEND ===== -->
<rect x="20" y="497" width="920" height="55" rx="4"
<rect x="20" y="486" width="920" height="55" rx="4"
fill="none" stroke="#ddd" />
<rect x="35" y="512" width="14" height="11" rx="2"
<rect x="35" y="500" width="14" height="11" rx="2"
fill="#e8f0fe" stroke="#4285f4" />
<text x="55" y="522" font-size="10">on-demand worker</text>
<text x="55" y="510" font-size="10">on-demand worker</text>
<rect x="190" y="512" width="14" height="11" rx="2"
<rect x="185" y="500" width="14" height="11" rx="2"
fill="#e6f4ea" stroke="#34a853" />
<text x="210" y="522" font-size="10">singleton thread</text>
<text x="205" y="510" font-size="10">singleton thread</text>
<rect x="340" y="512" width="14" height="11" rx="2"
<rect x="325" y="500" width="14" height="11" rx="2"
fill="#fef7e0" stroke="#f9ab00" />
<text x="360" y="522" font-size="10">storage / state</text>
<text x="345" y="510" font-size="10">storage / state</text>
<rect x="470" y="512" width="14" height="11" rx="2"
<rect x="445" y="500" width="14" height="11" rx="2"
fill="#fce8e6" stroke="#ea4335" />
<text x="490" y="522" font-size="10">external connection</text>
<text x="465" y="510" font-size="10">external connection</text>
<text x="35" y="544" font-size="10" fill="#666">
Solid arrows: TBQueue connections. Dashed: store access / dispatch. Workers connect to protocol clients in their column.
<rect x="595" y="500" width="14" height="11" rx="2"
fill="#f4f4f4" stroke="#999" />
<text x="615" y="510" font-size="10">API entry point</text>
<line x1="730" y1="505" x2="770" y2="505"
stroke="#c62828" stroke-dasharray="4,3" marker-end="url(#arr-x)" />
<text x="780" y="509" font-size="10">cross-protocol</text>
<text x="35" y="533" font-size="10" fill="#666">
Solid arrows: TBQueue flow. Dashed grey: store access. Dashed red: cross-protocol link. Workers use clients in their column.
</text>
</svg>

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 11 KiB