corrections
@@ -4,16 +4,16 @@ The SimpleX Agent builds duplex encrypted connections on top of [SimpleX client
|
||||
|
||||
This is **Layer 3** of the [SimpleX Network architecture](../protocol/overview-tjr.md). Layer 1 is the routers; Layer 2 is the [client libraries](CLIENT.md) that speak the wire protocols. The Agent adds the connection semantics that applications need.
|
||||
|
||||
**Source**: [`Simplex.Messaging.Agent`](../src/Simplex/Messaging/Agent.hs) — **Module spec**: [`spec/modules/Simplex/Messaging/Agent.md`](../spec/modules/Simplex/Messaging/Agent.md)
|
||||
**Source**: [`Simplex.Messaging.Agent`](../src/Simplex/Messaging/Agent.hs). **Module spec**: [`spec/modules/Simplex/Messaging/Agent.md`](../spec/modules/Simplex/Messaging/Agent.md)
|
||||
|
||||
## Connections
|
||||
|
||||
The Agent turns simplex (unidirectional) SMP queues into duplex connections, implementing the [Agent protocol](../protocol/agent-protocol.md):
|
||||
|
||||
- **Duplex connections**: each connection uses a pair of SMP queues — one for each direction. The queues can be on different routers chosen independently by each party. See the [duplex connection procedure](../protocol/agent-protocol.md) for the full handshake.
|
||||
- **Duplex connections**: each connection uses a pair of SMP queues - one for each direction. The queues can be on different routers chosen independently by each party. See the [duplex connection procedure](../protocol/agent-protocol.md) for the full handshake.
|
||||
- **Connection establishment**: one party creates a connection and generates an invitation (containing router address, queue ID, and public keys). The invitation is passed out-of-band (QR code, link, etc.). The other party joins by creating a reverse queue and completing the handshake.
|
||||
- **Connection links**: the Agent supports connection links (long and short) for sharing connection invitations via URLs. Short links use a separate SMP queue to store the full invitation, allowing compact QR codes.
|
||||
- **Queue rotation**: the Agent periodically rotates the underlying SMP queues, limiting the window for metadata correlation. Rotation is transparent to the application — the connection identity is stable while the underlying queues change.
|
||||
- **Queue rotation**: the Agent periodically rotates the underlying SMP queues, limiting the window for metadata correlation. Rotation is transparent to the application - the connection identity is stable while the underlying queues change.
|
||||
- **Redundant queues**: connections can use multiple queues for reliability. If one router becomes unreachable, messages flow through the remaining queues.
|
||||
|
||||
## Encryption
|
||||
@@ -46,7 +46,7 @@ The Agent manages push notification subscriptions for mobile devices, using the
|
||||
|
||||
The Agent is designed to be embedded as a Haskell library:
|
||||
|
||||
- **STM queues**: the application communicates with the Agent via STM queues. Commands go in (`ACommand`), events come out (`AEvent`). No serialization or parsing — direct Haskell values. The command/event types are defined in the [Agent Protocol module](../spec/modules/Simplex/Messaging/Agent/Protocol.md).
|
||||
- **STM queues**: the application communicates with the Agent via STM queues. Commands go in (`ACommand`), events come out (`AEvent`). No serialization or parsing - direct Haskell values. The command/event types are defined in the [Agent Protocol module](../spec/modules/Simplex/Messaging/Agent/Protocol.md).
|
||||
- **Async operation**: all network operations are asynchronous. The Agent manages internal worker threads for each router connection, message processing, and background tasks (cleanup, statistics, notification supervision). See the [Agent Client module spec](../spec/modules/Simplex/Messaging/Agent/Client.md) for worker architecture.
|
||||
- **Background mode**: on mobile platforms, the Agent can run in a reduced mode with only the message receiver active, minimizing resource usage when the app is backgrounded.
|
||||
- **Dual database backends**: the Agent supports both SQLite (for mobile/desktop) and PostgreSQL (for server deployments) as persistence backends, selected at compile time. See [Agent Store Interface](../spec/modules/Simplex/Messaging/Agent/Store/Interface.md) and [Agent Store Postgres](../spec/modules/Simplex/Messaging/Agent/Store/Postgres.md).
|
||||
@@ -70,24 +70,24 @@ The Agent is designed to be embedded as a Haskell library:
|
||||
|
||||
## Protocol references
|
||||
|
||||
- [Agent Protocol](../protocol/agent-protocol.md) — duplex connection procedure, message format
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) — architecture, trust model
|
||||
- [PQDR](../protocol/pqdr.md) — post-quantum double ratchet specification
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) — SMP queue operations used by the Agent
|
||||
- [XFTP Protocol](../protocol/xftp.md) — data packet operations for file transfer
|
||||
- [Push Notifications Protocol](../protocol/push-notifications.md) — NTF token and subscription management
|
||||
- [Agent Protocol](../protocol/agent-protocol.md) - duplex connection procedure, message format
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) - architecture, trust model
|
||||
- [PQDR](../protocol/pqdr.md) - post-quantum double ratchet specification
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) - SMP queue operations used by the Agent
|
||||
- [XFTP Protocol](../protocol/xftp.md) - data packet operations for file transfer
|
||||
- [Push Notifications Protocol](../protocol/push-notifications.md) - NTF token and subscription management
|
||||
## Peer library: Remote Control
|
||||
|
||||
The Agent exposes the [XRCP protocol](../protocol/xrcp.md) API for cross-device remote control (e.g., controlling a mobile app from a desktop). The actual logic is in the standalone [`Simplex.RemoteControl.Client`](../src/Simplex/RemoteControl/Client.hs) library — the Agent provides thin wrappers that pass through its random and multicast state. XRCP is not a managed Agent capability (no workers, persistence, or background supervision). See the [RemoteControl module specs](../spec/modules/Simplex/RemoteControl/Types.md).
|
||||
The Agent exposes the [XRCP protocol](../protocol/xrcp.md) API for cross-device remote control (e.g., controlling a mobile app from a desktop). The actual logic is in the standalone [`Simplex.RemoteControl.Client`](../src/Simplex/RemoteControl/Client.hs) library - the Agent provides thin wrappers that pass through its random and multicast state. XRCP is not a managed Agent capability (no workers, persistence, or background supervision). See the [RemoteControl module specs](../spec/modules/Simplex/RemoteControl/Types.md).
|
||||
|
||||
## Module specs
|
||||
|
||||
- [Agent](../spec/modules/Simplex/Messaging/Agent.md) — main Agent module, connection lifecycle, message processing
|
||||
- [Agent Client](../spec/modules/Simplex/Messaging/Agent/Client.md) — worker threads, router connections, subscription management
|
||||
- [Agent Protocol](../spec/modules/Simplex/Messaging/Agent/Protocol.md) — ACommand/AEvent types, connection invitations
|
||||
- [Agent Store Interface](../spec/modules/Simplex/Messaging/Agent/Store/Interface.md) — database abstraction for SQLite/Postgres
|
||||
- [Agent Store (AgentStore)](../spec/modules/Simplex/Messaging/Agent/Store/AgentStore.md) — connection, queue, and message persistence
|
||||
- [NtfSubSupervisor](../spec/modules/Simplex/Messaging/Agent/NtfSubSupervisor.md) — notification subscription management
|
||||
- [XFTP Agent](../spec/modules/Simplex/FileTransfer/Agent.md) — file transfer orchestration
|
||||
- [Ratchet](../spec/modules/Simplex/Messaging/Crypto/Ratchet.md) — double ratchet implementation
|
||||
- [SNTRUP761](../spec/modules/Simplex/Messaging/Crypto/SNTRUP761.md) — post-quantum KEM
|
||||
- [Agent](../spec/modules/Simplex/Messaging/Agent.md) - main Agent module, connection lifecycle, message processing
|
||||
- [Agent Client](../spec/modules/Simplex/Messaging/Agent/Client.md) - worker threads, router connections, subscription management
|
||||
- [Agent Protocol](../spec/modules/Simplex/Messaging/Agent/Protocol.md) - ACommand/AEvent types, connection invitations
|
||||
- [Agent Store Interface](../spec/modules/Simplex/Messaging/Agent/Store/Interface.md) - database abstraction for SQLite/Postgres
|
||||
- [Agent Store (AgentStore)](../spec/modules/Simplex/Messaging/Agent/Store/AgentStore.md) - connection, queue, and message persistence
|
||||
- [NtfSubSupervisor](../spec/modules/Simplex/Messaging/Agent/NtfSubSupervisor.md) - notification subscription management
|
||||
- [XFTP Agent](../spec/modules/Simplex/FileTransfer/Agent.md) - file transfer orchestration
|
||||
- [Ratchet](../spec/modules/Simplex/Messaging/Crypto/Ratchet.md) - double ratchet implementation
|
||||
- [SNTRUP761](../spec/modules/Simplex/Messaging/Crypto/SNTRUP761.md) - post-quantum KEM
|
||||
|
||||
@@ -8,7 +8,7 @@ This is **Layer 2** of the [SimpleX Network architecture](../protocol/overview-t
|
||||
|
||||
**Source**: [`Simplex.Messaging.Client`](../src/Simplex/Messaging/Client.hs). For architecture and module specs, see [SMP Client](../spec/clients.md#smp-client-protocolclient).
|
||||
|
||||
The SMP client connects to SMP routers and manages simplex messaging queues — the fundamental addressing primitive of the SimpleX Network. Each simplex queue is a unidirectional, ordered sequence of fixed-size packets (16,384 bytes) with separate cryptographic credentials for sending and receiving. The queue model and command set are defined in the [SMP protocol](../protocol/simplex-messaging.md).
|
||||
The SMP client connects to SMP routers and manages simplex messaging queues, the fundamental addressing primitive of the SimpleX Network. Each simplex queue is a unidirectional, ordered sequence of fixed-size packets (16,384 bytes) with separate cryptographic credentials for sending and receiving. The queue model and command set are defined in the [SMP protocol](../protocol/simplex-messaging.md).
|
||||
|
||||
### Capabilities
|
||||
|
||||
@@ -31,17 +31,30 @@ The client uses a functional Haskell API with STM queues for asynchronous event
|
||||
|
||||
Routers are identified by the SHA-256 hash of their CA certificate fingerprint, not by hostname. The client validates the full X.509 certificate chain on every TLS connection and compares the CA fingerprint against the expected hash from the queue address. This means a DNS or IP-level attacker who cannot produce the correct certificate is detected at connection time.
|
||||
|
||||
## SMPClientAgent
|
||||
|
||||
**Source**: [`Simplex.Messaging.Client.Agent`](../src/Simplex/Messaging/Client/Agent.hs). For architecture and module specs, see [SMPClientAgent](../spec/clients.md#smpclientagent).
|
||||
|
||||
Connection manager that multiplexes multiple SMP client connections. Maintains one ProtocolClient per SMP router, tracks queue and service subscriptions, and handles reconnection with exponential backoff. Used by the SMP router (for proxy forwarding) and the NTF router (for message subscriptions).
|
||||
|
||||
### Capabilities
|
||||
|
||||
- **Connection pooling**: maintains a pool of ProtocolClient connections keyed by SMP router, creating connections on demand and reusing existing ones
|
||||
- **Subscription tracking**: tracks active and pending subscriptions (both queue-based and service-based) with automatic state transitions on connect/disconnect
|
||||
- **Automatic reconnection**: on connection loss, moves subscriptions from active to pending, then spawns a background worker that retries with backoff and resubscribes
|
||||
- **Session-scoped disconnect handling**: uses session IDs to ensure only subscriptions belonging to the disconnected session are affected, preventing races with newly established connections
|
||||
|
||||
## XFTP Client
|
||||
|
||||
**Source**: [`Simplex.FileTransfer.Client`](../src/Simplex/FileTransfer/Client.hs). For architecture and module specs, see [XFTP Client](../spec/clients.md#xftp-client).
|
||||
|
||||
The XFTP client connects to XFTP routers and manages data packets — individually addressed blocks used for larger payload delivery. Data packets come in fixed sizes (64KB, 256KB, 1MB, 4MB), hiding the actual payload size. The XFTP protocol runs over HTTP/2, simplifying browser integration. The data packet lifecycle and command set are defined in the [XFTP protocol](../protocol/xftp.md).
|
||||
The XFTP client connects to XFTP routers and manages data packets, individually addressed blocks used for larger payload delivery. Data packets come in fixed sizes (64KB, 256KB, 1MB, 4MB), hiding the actual payload size. The XFTP protocol runs over HTTP/2, simplifying browser integration. The data packet lifecycle and command set are defined in the [XFTP protocol](../protocol/xftp.md).
|
||||
|
||||
### Capabilities
|
||||
|
||||
- **Data packet creation**: create data packets on routers with sender, recipient, and optional additional recipient credentials. See the [XFTP protocol](../protocol/xftp.md) for credential roles and packet lifecycle.
|
||||
- **Send** (FPUT): send encrypted data to the router in a single HTTP/2 streaming request (command + body)
|
||||
- **Receive** (FGET): receive data packets with per-request ephemeral Diffie-Hellman key exchange, providing forward secrecy — compromising one DH key does not reveal other received data packets
|
||||
- **Receive** (FGET): receive data packets with per-request ephemeral Diffie-Hellman key exchange, providing forward secrecy: compromising one DH key does not reveal other received data packets
|
||||
- **Acknowledgment and deletion**: recipients acknowledge receipt; senders delete data packets after delivery
|
||||
|
||||
## NTF Client
|
||||
@@ -69,15 +82,15 @@ These libraries are appropriate when the application manages its own encryption
|
||||
|
||||
The following capabilities require the [Agent](AGENT.md) (Layer 3):
|
||||
|
||||
- **Duplex connections** — the Agent pairs two simplex queues into a duplex connection
|
||||
- **End-to-end encryption** — the Agent manages double ratchet with post-quantum extensions
|
||||
- **File transfer** — the Agent handles chunking, encryption, padding, multi-router distribution, and reassembly
|
||||
- **Queue rotation** — the Agent transparently rotates queues to limit metadata correlation
|
||||
- **Connection discovery** — connection links, short links, and contact addresses are Agent-level abstractions
|
||||
- **Push notifications** — notification token management and subscription is Agent-level
|
||||
- **Duplex connections** - the Agent pairs two simplex queues into a duplex connection
|
||||
- **End-to-end encryption** - the Agent manages double ratchet with post-quantum extensions
|
||||
- **File transfer** - the Agent handles chunking, encryption, padding, multi-router distribution, and reassembly
|
||||
- **Queue rotation** - the Agent transparently rotates queues to limit metadata correlation
|
||||
- **Connection discovery** - connection links, short links, and contact addresses are Agent-level abstractions
|
||||
- **Push notifications** - notification token management and subscription is Agent-level
|
||||
|
||||
## Protocol references
|
||||
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) — SMP wire format, commands, and security properties
|
||||
- [XFTP Protocol](../protocol/xftp.md) — XFTP wire format, data packet lifecycle
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) — architecture, trust model, and design rationale
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) - SMP wire format, commands, and security properties
|
||||
- [XFTP Protocol](../protocol/xftp.md) - XFTP wire format, data packet lifecycle
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) - architecture, trust model, and design rationale
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SimpleX Routers — Deployment and Configuration
|
||||
# SimpleX Routers: Deployment and Configuration
|
||||
|
||||
SimpleX routers are the network infrastructure of the [SimpleX Network](../protocol/overview-tjr.md). They accept, buffer, and deliver data packets between endpoints. Each router operates independently and can be run by any party on standard computing hardware.
|
||||
|
||||
@@ -6,7 +6,7 @@ This document covers deployment and advanced configuration. For an overview of t
|
||||
|
||||
## SMP Router
|
||||
|
||||
The SMP router provides messaging queues — unidirectional, ordered sequences of fixed-size packets (16,384 bytes each). It implements the [SimpleX Messaging Protocol](../protocol/simplex-messaging.md). For architecture and module specs, see [SMP Router](../spec/routers.md#smp-router).
|
||||
The SMP router provides messaging queues - unidirectional, ordered sequences of fixed-size packets (16,384 bytes each). It implements the [SimpleX Messaging Protocol](../protocol/simplex-messaging.md). For architecture and module specs, see [SMP Router](../spec/routers.md#smp-router).
|
||||
|
||||
### Advanced configuration
|
||||
|
||||
@@ -35,7 +35,7 @@ echo 'PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zprofile
|
||||
|
||||
## XFTP Router
|
||||
|
||||
The XFTP router accepts and delivers data packets over HTTP/2 — individually addressed blocks in fixed sizes (64KB, 256KB, 1MB, 4MB). It implements the [XFTP protocol](../protocol/xftp.md). Data packets are used for larger payload delivery (files, media) where SMP queue packet sizes would be inefficient. The use of HTTP/2 simplifies browser integration. For architecture and module specs, see [XFTP Router](../spec/routers.md#xftp-router).
|
||||
The XFTP router accepts and delivers data packets over HTTP/2 - individually addressed blocks in fixed sizes (64KB, 256KB, 1MB, 4MB). It implements the [XFTP protocol](../protocol/xftp.md). Data packets are used for larger payload delivery (files, media) where SMP queue packet sizes would be inefficient. The use of HTTP/2 simplifies browser integration. For architecture and module specs, see [XFTP Router](../spec/routers.md#xftp-router).
|
||||
|
||||
Initialize with `xftp-server init` and configure storage quota in `xftp-server.ini`.
|
||||
|
||||
@@ -66,7 +66,7 @@ Prebuilt images are available from [Docker Hub](https://hub.docker.com/r/simplex
|
||||
|
||||
2. Run:
|
||||
|
||||
**SMP router** — change `your_ip_or_domain`; `-e "PASS=password"` is optional:
|
||||
**SMP router** - change `your_ip_or_domain`; `-e "PASS=password"` is optional:
|
||||
```sh
|
||||
docker run -d \
|
||||
-e "ADDR=your_ip_or_domain" \
|
||||
@@ -77,7 +77,7 @@ Prebuilt images are available from [Docker Hub](https://hub.docker.com/r/simplex
|
||||
simplexchat/smp-server:latest
|
||||
```
|
||||
|
||||
**XFTP router** — change `your_ip_or_domain` and `maximum_storage`:
|
||||
**XFTP router** - change `your_ip_or_domain` and `maximum_storage`:
|
||||
```sh
|
||||
docker run -d \
|
||||
-e "ADDR=your_ip_or_domain" \
|
||||
@@ -160,12 +160,12 @@ Then run with the same Docker commands as above, replacing `simplexchat/smp-serv
|
||||
|
||||
### Linode StackScript
|
||||
|
||||
[Deploy via Linode StackScript](https://cloud.linode.com/stackscripts/748014) — Shared CPU Nanode with 1GB is sufficient.
|
||||
[Deploy via Linode StackScript](https://cloud.linode.com/stackscripts/748014). Shared CPU Nanode with 1GB is sufficient.
|
||||
|
||||
Configuration options:
|
||||
- SMP Server store log flag for queue persistence (recommended)
|
||||
- [Linode API token](https://www.linode.com/docs/guides/getting-started-with-the-linode-api#get-an-access-token) for automatic DNS and tagging (scopes: read/write for "linodes" and "domains")
|
||||
- Domain name (e.g., `smp1.example.com`) — the [domain must exist](https://cloud.linode.com/domains/create) in your Linode account
|
||||
- Domain name (e.g., `smp1.example.com`) - the [domain must exist](https://cloud.linode.com/domains/create) in your Linode account
|
||||
|
||||
After deployment (up to 5 minutes), get the server address from Linode tags or SSH: `smp://<fingerprint>@<fqdn>`.
|
||||
|
||||
@@ -188,7 +188,7 @@ SMP and XFTP routers expose Prometheus metrics via a control port. The control p
|
||||
|
||||
## Protocol references
|
||||
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) — SMP wire format and security properties
|
||||
- [XFTP Protocol](../protocol/xftp.md) — data packet protocol
|
||||
- [Push Notifications Protocol](../protocol/push-notifications.md) — NTF protocol
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) — architecture and trust model
|
||||
- [SimpleX Messaging Protocol](../protocol/simplex-messaging.md) - SMP wire format and security properties
|
||||
- [XFTP Protocol](../protocol/xftp.md) - data packet protocol
|
||||
- [Push Notifications Protocol](../protocol/push-notifications.md) - NTF protocol
|
||||
- [SimpleX Network overview](../protocol/overview-tjr.md) - architecture and trust model
|
||||
|
||||
@@ -14,9 +14,9 @@ Generic protocol client used for both SMP and NTF connections. Manages a single
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Command/response flow
|
||||
### Command/result flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -33,7 +33,7 @@ sequenceDiagram
|
||||
|
||||
participant Router as SMP Router
|
||||
|
||||
C->>SC: mkTransmission (generate CorrId, create Request with empty responseVar)
|
||||
C->>SC: mkTransmission<br/>(generate CorrId, create Request<br/>with empty responseVar)
|
||||
C->>SQ: write (Request, encoded command)
|
||||
S->>SQ: read
|
||||
S-->>S: check pending flag (drop if timed out)
|
||||
@@ -65,15 +65,19 @@ Connection manager that multiplexes multiple ProtocolClient connections. Tracks
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Connection lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Consumer<br>(router / app)
|
||||
participant A as SMPClientAgent
|
||||
participant PC as ProtocolClient
|
||||
|
||||
box
|
||||
participant A as SMPClientAgent
|
||||
participant PC as ProtocolClient
|
||||
end
|
||||
|
||||
participant Router as SMP Router
|
||||
|
||||
C->>A: getSMPServerClient'' (server)
|
||||
@@ -112,11 +116,11 @@ sequenceDiagram
|
||||
|
||||
**Module specs**: [Client](modules/Simplex/FileTransfer/Client.md) · [Protocol](modules/Simplex/FileTransfer/Protocol.md) · [HTTP/2 Client](modules/Simplex/Messaging/Transport/HTTP2/Client.md)
|
||||
|
||||
Stateless wrapper around HTTP2Client. XFTPClient adds no threads of its own — each operation is a synchronous HTTP/2 request/response. Serialization and multiplexing happen inside HTTP2Client's internal request queue and process thread.
|
||||
Stateless wrapper around HTTP2Client. XFTPClient adds no threads of its own; each operation is a synchronous HTTP/2 request/response. Serialization and multiplexing happen inside HTTP2Client's internal request queue and process thread.
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Upload/download flow
|
||||
|
||||
@@ -156,7 +160,7 @@ sequenceDiagram
|
||||
|
||||
**Module specs**: [Client](modules/Simplex/Messaging/Notifications/Client.md) · [Protocol](modules/Simplex/Messaging/Notifications/Protocol.md)
|
||||
|
||||
Type alias for ProtocolClient — same architecture as SMP Client:
|
||||
Type alias for ProtocolClient - same architecture as SMP Client:
|
||||
|
||||
```haskell
|
||||
type NtfClient = ProtocolClient NTFVersion ErrorType NtfResponse
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="415" y="22" text-anchor="middle" font-size="15" font-weight="bold">NTF Router -- Component Topology</text>
|
||||
|
||||
<!-- ===== PER-CLIENT GROUP (left) ===== -->
|
||||
<rect x="25" y="40" width="300" height="170" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.4 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 480" font-family="monospace" font-size="12">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 740 400" 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">
|
||||
@@ -10,137 +10,134 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="375" y="22" text-anchor="middle" font-size="15" font-weight="bold">SMPClientAgent -- Component Topology</text>
|
||||
<!-- ===== CONSUMER (top left) ===== -->
|
||||
<text x="15" y="35" font-size="9" fill="#999">consumer</text>
|
||||
<text x="15" y="48" font-size="9" fill="#999">(NTF router /</text>
|
||||
<text x="15" y="61" font-size="9" fill="#999"> SMP proxy /</text>
|
||||
<text x="15" y="74" font-size="9" fill="#999"> application)</text>
|
||||
|
||||
<!-- ===== CONSUMER (top) ===== -->
|
||||
<text x="15" y="55" font-size="9" fill="#999">consumer</text>
|
||||
<text x="15" y="68" font-size="9" fill="#999">(NTF router /</text>
|
||||
<text x="15" y="81" font-size="9" fill="#999"> SMP proxy /</text>
|
||||
<text x="15" y="94" font-size="9" fill="#999"> application)</text>
|
||||
|
||||
<!-- msgQ -->
|
||||
<rect x="105" y="45" width="200" height="38" rx="4"
|
||||
<!-- ===== agentQ (upper right) ===== -->
|
||||
<rect x="360" y="15" width="210" height="35" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="205" y="63" text-anchor="middle" font-weight="bold">msgQ</text>
|
||||
<text x="205" y="77" text-anchor="middle" font-size="10">(TBQueue, server messages)</text>
|
||||
|
||||
<!-- consumer <- msgQ -->
|
||||
<line x1="105" y1="64" x2="80" y2="64"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- agentQ -->
|
||||
<rect x="340" y="45" width="230" height="38" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="455" y="63" text-anchor="middle" font-weight="bold">agentQ</text>
|
||||
<text x="455" y="77" text-anchor="middle" font-size="10">(TBQueue SMPClientAgentEvent)</text>
|
||||
<text x="465" y="33" text-anchor="middle" font-weight="bold">agentQ</text>
|
||||
<text x="465" y="46" text-anchor="middle" font-size="10">(TBQueue SMPClientAgentEvent)</text>
|
||||
|
||||
<!-- consumer <- agentQ -->
|
||||
<line x1="340" y1="55" x2="80" y2="55"
|
||||
<line x1="360" y1="32" x2="80" y2="32"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- agentQ events note -->
|
||||
<text x="580" y="50" font-size="9" fill="#666">CAConnected</text>
|
||||
<text x="580" y="61" font-size="9" fill="#666">CADisconnected</text>
|
||||
<text x="580" y="72" font-size="9" fill="#666">CASubscribed / CASubError</text>
|
||||
<text x="580" y="83" font-size="9" fill="#666">CAServiceDisconnected</text>
|
||||
<text x="580" y="94" font-size="9" fill="#666">CAServiceSubscribed / SubError</text>
|
||||
<text x="580" y="22" font-size="9" fill="#666">CAConnected / Disconnected</text>
|
||||
<text x="580" y="33" font-size="9" fill="#666">CASubscribed / SubError</text>
|
||||
<text x="580" y="44" font-size="9" fill="#666">CAServiceDisconnected</text>
|
||||
<text x="580" y="55" font-size="9" fill="#666">CAServiceSubscribed / SubError</text>
|
||||
<text x="580" y="66" font-size="9" fill="#666">CAServiceUnavailable</text>
|
||||
|
||||
<!-- ===== msgQ (upper left, below agentQ) ===== -->
|
||||
<rect x="130" y="55" width="195" height="35" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="227" y="73" text-anchor="middle" font-weight="bold">msgQ</text>
|
||||
<text x="227" y="86" text-anchor="middle" font-size="10">(TBQueue, server messages)</text>
|
||||
|
||||
<!-- consumer <- msgQ -->
|
||||
<line x1="130" y1="72" x2="80" y2="72"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- ===== AGENT CORE ===== -->
|
||||
<rect x="25" y="105" width="700" height="175" rx="6"
|
||||
<rect x="25" y="100" width="700" height="82" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
<text x="35" y="120" fill="#888" font-size="10">SMPClientAgent (connection manager)</text>
|
||||
<text x="35" y="113" fill="#888" font-size="10">SMPClientAgent (connection manager)</text>
|
||||
|
||||
<!-- smpClients -->
|
||||
<rect x="45" y="135" width="220" height="48" rx="4"
|
||||
<rect x="45" y="120" width="170" height="48" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="155" y="156" text-anchor="middle" font-weight="bold">smpClients</text>
|
||||
<text x="155" y="174" text-anchor="middle" font-size="10">(TMap SMPServer SMPClientVar)</text>
|
||||
|
||||
<!-- subscription tracking -->
|
||||
<rect x="290" y="135" width="250" height="56" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="415" y="149" text-anchor="middle" font-size="10">activeQueueSubs / pendingQueueSubs</text>
|
||||
<text x="415" y="161" text-anchor="middle" font-size="9" fill="#666">(TMap SMPServer (TMap QueueId ...))</text>
|
||||
<text x="415" y="174" text-anchor="middle" font-size="10">activeServiceSubs / pendingServiceSubs</text>
|
||||
<text x="415" y="186" text-anchor="middle" font-size="9" fill="#666">(TMap SMPServer (TVar (Maybe ...)))</text>
|
||||
<text x="130" y="141" text-anchor="middle" font-weight="bold">smpClients</text>
|
||||
<text x="130" y="159" text-anchor="middle" font-size="9">(TMap SMPServer SMPClientVar)</text>
|
||||
|
||||
<!-- smpClients -> msgQ (server messages forwarded up) -->
|
||||
<line x1="155" y1="135" x2="155" y2="85"
|
||||
<line x1="145" y1="120" x2="145" y2="92"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- smpSubWorkers -->
|
||||
<rect x="250" y="120" width="130" height="48" rx="4"
|
||||
fill="#e6f4ea" stroke="#34a853" />
|
||||
<text x="315" y="141" text-anchor="middle" font-size="11">smpSubWorkers</text>
|
||||
<text x="315" y="159" text-anchor="middle" font-size="9" fill="#666">(one per server)</text>
|
||||
|
||||
<!-- workers -> smpClients (reconnect, dashed) -->
|
||||
<line x1="250" y1="144" x2="215" y2="144"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="222" y="138" font-size="8" fill="#555">reconnect</text>
|
||||
|
||||
<!-- subscription tracking -->
|
||||
<rect x="415" y="118" width="275" height="56" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="552" y="134" text-anchor="middle" font-size="10">activeQueueSubs / pendingQueueSubs</text>
|
||||
<text x="552" y="146" text-anchor="middle" font-size="9" fill="#666">(TMap SMPServer (TMap QueueId ...))</text>
|
||||
<text x="552" y="159" text-anchor="middle" font-size="10">activeServiceSubs / pendingServiceSubs</text>
|
||||
<text x="552" y="171" text-anchor="middle" font-size="9" fill="#666">(TMap SMPServer (TVar (Maybe ...)))</text>
|
||||
|
||||
<!-- subscription state -> agentQ (connection events forwarded up) -->
|
||||
<line x1="415" y1="135" x2="415" y2="85"
|
||||
<line x1="465" y1="118" x2="465" y2="52"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- reconnect workers -->
|
||||
<rect x="565" y="135" width="140" height="48" rx="4"
|
||||
fill="#e6f4ea" stroke="#34a853" />
|
||||
<text x="635" y="156" text-anchor="middle" font-size="11">smpSubWorkers</text>
|
||||
<text x="635" y="174" text-anchor="middle" font-size="9" fill="#666">(one per server)</text>
|
||||
|
||||
<!-- workers -> smpClients (reconnect) -->
|
||||
<line x1="565" y1="159" x2="265" y2="159"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="390" y="155" font-size="9" fill="#555">reconnect + resubscribe</text>
|
||||
|
||||
<!-- getSMPServerClient'' label -->
|
||||
<text x="50" y="210" font-size="10" fill="#666">getSMPServerClient'': get or create client</text>
|
||||
<text x="50" y="224" font-size="10" fill="#666">connectClient: create ProtocolClient, register disconnect handler</text>
|
||||
<text x="50" y="238" font-size="10" fill="#666">on disconnect: filter by SessionId, move active → pending, notify agentQ, spawn worker</text>
|
||||
<text x="50" y="252" font-size="10" fill="#666">worker: retry connect with backoff, resubscribe pending subs</text>
|
||||
<text x="50" y="266" font-size="10" fill="#666">subscribeQueuesNtfs / subscribeServiceNtfs: subscribe + track state</text>
|
||||
|
||||
<!-- ===== PROTOCOL CLIENTS (bottom) ===== -->
|
||||
<rect x="25" y="300" width="700" height="95" rx="6"
|
||||
<rect x="25" y="198" width="700" height="72" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
<text x="35" y="315" fill="#888" font-size="10">ProtocolClient connections (one per SMP Router)</text>
|
||||
<text x="35" y="213" fill="#888" font-size="10">ProtocolClient connections (one per SMP Router)</text>
|
||||
|
||||
<!-- Client 1 -->
|
||||
<rect x="45" y="330" width="150" height="48" rx="4"
|
||||
<rect x="45" y="220" width="140" height="40" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="120" y="351" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="120" y="369" text-anchor="middle" font-size="10">→ SMP Router A</text>
|
||||
<text x="115" y="238" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="115" y="253" text-anchor="middle" font-size="10">→ SMP Router A</text>
|
||||
|
||||
<!-- Client 2 -->
|
||||
<rect x="220" y="330" width="150" height="48" rx="4"
|
||||
<rect x="210" y="220" width="140" height="40" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="295" y="351" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="295" y="369" text-anchor="middle" font-size="10">→ SMP Router B</text>
|
||||
<text x="280" y="238" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="280" y="253" text-anchor="middle" font-size="10">→ SMP Router B</text>
|
||||
|
||||
<!-- Client N -->
|
||||
<rect x="395" y="330" width="150" height="48" rx="4"
|
||||
<rect x="375" y="220" width="140" height="40" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="470" y="351" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="470" y="369" text-anchor="middle" font-size="10">→ SMP Router N</text>
|
||||
<text x="445" y="238" text-anchor="middle">ProtocolClient</text>
|
||||
<text x="445" y="253" text-anchor="middle" font-size="10">→ SMP Router N</text>
|
||||
|
||||
<!-- dots -->
|
||||
<text x="560" y="360" font-size="14" fill="#888">...</text>
|
||||
<text x="530" y="245" font-size="14" fill="#888">...</text>
|
||||
|
||||
<!-- smpClients -> clients -->
|
||||
<line x1="100" y1="183" x2="100" y2="328"
|
||||
<line x1="100" y1="168" x2="100" y2="218"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
<line x1="200" y1="183" x2="295" y2="328"
|
||||
<line x1="185" y1="168" x2="265" y2="218"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- ===== NOTES ===== -->
|
||||
<text x="45" y="292" font-size="10" fill="#666">getSMPServerClient'': get or create client</text>
|
||||
<text x="45" y="306" font-size="10" fill="#666">connectClient: create ProtocolClient, register disconnect handler</text>
|
||||
<text x="45" y="320" font-size="10" fill="#666">on disconnect: filter by SessionId, move active to pending, notify agentQ, spawn worker</text>
|
||||
<text x="45" y="334" font-size="10" fill="#666">worker: retry connect with backoff, resubscribe pending subs</text>
|
||||
<text x="45" y="348" font-size="10" fill="#666">subscribeQueuesNtfs / subscribeServiceNtfs: subscribe + track state</text>
|
||||
|
||||
<!-- ===== LEGEND ===== -->
|
||||
<rect x="25" y="415" width="700" height="50" rx="4"
|
||||
<rect x="25" y="365" width="700" height="30" rx="4"
|
||||
fill="none" stroke="#ddd" />
|
||||
|
||||
<rect x="40" y="428" width="14" height="11" rx="2"
|
||||
<rect x="40" y="374" width="14" height="11" rx="2"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="60" y="438" font-size="10">ProtocolClient</text>
|
||||
<text x="60" y="384" font-size="10">ProtocolClient</text>
|
||||
|
||||
<rect x="185" y="428" width="14" height="11" rx="2"
|
||||
<rect x="185" y="374" width="14" height="11" rx="2"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="205" y="438" font-size="10">state / queue</text>
|
||||
<text x="205" y="384" font-size="10">state / queue</text>
|
||||
|
||||
<rect x="310" y="428" width="14" height="11" rx="2"
|
||||
<rect x="310" y="374" width="14" height="11" rx="2"
|
||||
fill="#e6f4ea" stroke="#34a853" />
|
||||
<text x="330" y="438" font-size="10">background worker</text>
|
||||
<text x="330" y="384" font-size="10">background worker</text>
|
||||
|
||||
<text x="40" y="456" font-size="10" fill="#666">
|
||||
Solid arrows: TBQueue flow. Dashed: reconnection / resubscription.
|
||||
<text x="480" y="384" font-size="10" fill="#666">
|
||||
Solid arrows: TBQueue flow. Dashed: reconnection.
|
||||
</text>
|
||||
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.7 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 420" font-family="monospace" font-size="12">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 380" 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">
|
||||
@@ -10,139 +10,160 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="360" y="22" text-anchor="middle" font-size="15" font-weight="bold">SMP Client (ProtocolClient) -- Component Topology</text>
|
||||
|
||||
<!-- ===== PER-CONNECTION GROUP ===== -->
|
||||
<rect x="120" y="38" width="480" height="240" rx="6"
|
||||
<rect x="100" y="15" width="435" height="250" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
<text x="130" y="53" fill="#888" font-size="10">per connection (raceAny_ -- any thread exit tears down connection)</text>
|
||||
<text x="110" y="30" fill="#888" font-size="10">per connection (raceAny_: any exit tears down all threads)</text>
|
||||
|
||||
<!-- caller label + arrow -->
|
||||
<text x="15" y="105" font-size="9" fill="#999">caller</text>
|
||||
<text x="10" y="118" font-size="9" fill="#999">(Agent/</text>
|
||||
<text x="10" y="131" font-size="9" fill="#999"> router)</text>
|
||||
<!-- ===== MONITOR (optional, above sndQ area) ===== -->
|
||||
<rect x="275" y="38" width="88" height="24" rx="4"
|
||||
fill="#f5f5f5" stroke="#bbb" />
|
||||
<text x="319" y="55" text-anchor="middle" font-size="11">monitor</text>
|
||||
<text x="370" y="54" font-size="9" fill="#bbb">optional</text>
|
||||
|
||||
<!-- caller -> sndQ (sendProtocolCommand) -->
|
||||
<line x1="55" y1="115" x2="138" y2="115"
|
||||
<!-- monitor -> API (PING via sendProtocolCommand) -->
|
||||
<line x1="300" y1="62" x2="265" y2="74"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="305" y="73" font-size="9" fill="#555">PING</text>
|
||||
|
||||
<!-- ===== ROW 1: SEND PATH ===== -->
|
||||
|
||||
<!-- caller label -->
|
||||
<text x="15" y="92" font-size="9" fill="#999">caller</text>
|
||||
<text x="10" y="105" font-size="9" fill="#999">(Agent /</text>
|
||||
<text x="10" y="118" font-size="9" fill="#999"> router)</text>
|
||||
|
||||
<!-- caller -> API -->
|
||||
<line x1="55" y1="98" x2="143" y2="98"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
<text x="73" y="109" font-size="9" fill="#999">commands</text>
|
||||
|
||||
<!-- API functions block -->
|
||||
<rect x="145" y="76" width="165" height="42" rx="4"
|
||||
fill="#f4f4f4" stroke="#999" />
|
||||
<text x="227" y="93" text-anchor="middle" font-size="10">sendProtocolCommand</text>
|
||||
<text x="227" y="107" text-anchor="middle" font-size="10">mkTransmission</text>
|
||||
|
||||
<!-- API -> sndQ -->
|
||||
<line x1="310" y1="97" x2="335" y2="97"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- sndQ -->
|
||||
<rect x="140" y="90" width="120" height="48" rx="4"
|
||||
<rect x="337" y="82" width="88" height="34" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="200" y="111" text-anchor="middle" font-weight="bold">sndQ</text>
|
||||
<text x="200" y="129" text-anchor="middle" font-size="10">(TBQueue, 64)</text>
|
||||
<text x="381" y="98" text-anchor="middle" font-weight="bold">sndQ</text>
|
||||
<text x="381" y="111" text-anchor="middle" font-size="9">(TBQueue, 64)</text>
|
||||
|
||||
<!-- sndQ -> send -->
|
||||
<line x1="260" y1="114" x2="298" y2="114"
|
||||
<line x1="425" y1="97" x2="448" y2="97"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- send thread -->
|
||||
<rect x="300" y="68" width="100" height="34" rx="4"
|
||||
<rect x="450" y="84" width="60" height="28" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="350" y="90" text-anchor="middle">send</text>
|
||||
<text x="480" y="103" text-anchor="middle">send</text>
|
||||
|
||||
<!-- send -> network -->
|
||||
<line x1="400" y1="85" x2="498" y2="85"
|
||||
<!-- send -> Router (exits per-connection box) -->
|
||||
<line x1="510" y1="97" x2="543" y2="97"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- Router label (outside box) -->
|
||||
<text x="548" y="88" font-size="9" fill="#999">SMP</text>
|
||||
<text x="548" y="101" font-size="9" fill="#999">Router</text>
|
||||
<text x="548" y="114" font-size="9" fill="#999">(TLS)</text>
|
||||
|
||||
<!-- ===== ROW 2: RECEIVE PATH + SENTCOMMANDS ===== -->
|
||||
|
||||
<!-- API -> sentCommands (insert CorrId + Request) -->
|
||||
<line x1="227" y1="118" x2="227" y2="148"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
<text x="235" y="138" font-size="9" fill="#555">insert</text>
|
||||
|
||||
<!-- sentCommands -->
|
||||
<rect x="145" y="150" width="165" height="38" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="227" y="167" text-anchor="middle" font-weight="bold">sentCommands</text>
|
||||
<text x="227" y="182" text-anchor="middle" font-size="9">(TMap CorrId Request)</text>
|
||||
|
||||
<!-- sentCommands -> caller (responseVar, dashed) -->
|
||||
<line x1="145" y1="169" x2="55" y2="125"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="62" y="152" font-size="9" fill="#555">responseVar</text>
|
||||
<text x="62" y="164" font-size="9" fill="#555">(TMVar)</text>
|
||||
|
||||
<!-- Router -> receive (enters per-connection box) -->
|
||||
<line x1="543" y1="163" x2="510" y2="163"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- receive thread -->
|
||||
<rect x="300" y="118" width="100" height="34" rx="4"
|
||||
<rect x="450" y="150" width="60" height="28" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="350" y="140" text-anchor="middle">receive</text>
|
||||
|
||||
<!-- network -> receive -->
|
||||
<line x1="498" y1="135" x2="400" y2="135"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
|
||||
<!-- network label -->
|
||||
<text x="505" y="113" font-size="9" fill="#999">SMP</text>
|
||||
<text x="505" y="126" font-size="9" fill="#999">Router</text>
|
||||
<text x="505" y="139" font-size="9" fill="#999">(TLS)</text>
|
||||
<text x="480" y="169" text-anchor="middle">receive</text>
|
||||
|
||||
<!-- receive -> rcvQ -->
|
||||
<line x1="350" y1="152" x2="350" y2="168"
|
||||
<line x1="450" y1="163" x2="425" y2="163"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- rcvQ -->
|
||||
<rect x="290" y="170" width="120" height="48" rx="4"
|
||||
<rect x="337" y="148" width="88" height="34" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="350" y="191" text-anchor="middle" font-weight="bold">rcvQ</text>
|
||||
<text x="350" y="209" text-anchor="middle" font-size="10">(TBQueue, 64)</text>
|
||||
<text x="381" y="164" text-anchor="middle" font-weight="bold">rcvQ</text>
|
||||
<text x="381" y="177" text-anchor="middle" font-size="9">(TBQueue, 64)</text>
|
||||
|
||||
<!-- ===== ROW 3: PROCESS ===== -->
|
||||
|
||||
<!-- rcvQ -> process -->
|
||||
<line x1="350" y1="218" x2="350" y2="234"
|
||||
<line x1="370" y1="182" x2="300" y2="216"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
|
||||
<!-- process -> sentCommands (match CorrId, dashed upward) -->
|
||||
<line x1="245" y1="218" x2="245" y2="190"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="252" y="208" font-size="9" fill="#555">match</text>
|
||||
|
||||
<!-- process thread -->
|
||||
<rect x="300" y="236" width="100" height="34" rx="4"
|
||||
<rect x="195" y="220" width="110" height="28" rx="4"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="350" y="258" text-anchor="middle">process</text>
|
||||
<text x="250" y="239" text-anchor="middle">process</text>
|
||||
|
||||
<!-- sentCommands -->
|
||||
<rect x="140" y="170" width="130" height="48" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="205" y="191" text-anchor="middle" font-weight="bold">sentCommands</text>
|
||||
<text x="205" y="209" text-anchor="middle" font-size="10">(TMap CorrId Request)</text>
|
||||
<!-- ===== msgQ (outside per-connection box) ===== -->
|
||||
|
||||
<!-- process -> sentCommands (match CorrId) -->
|
||||
<line x1="300" y1="253" x2="270" y2="220"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="268" y="244" font-size="9" fill="#555">match</text>
|
||||
|
||||
<!-- process -> responseVar (back to caller) -->
|
||||
<line x1="300" y1="260" x2="60" y2="145"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="130" y="220" font-size="9" fill="#555">responseVar</text>
|
||||
<text x="130" y="232" font-size="9" fill="#555">(TMVar)</text>
|
||||
|
||||
<!-- monitor thread (optional) -->
|
||||
<rect x="430" y="190" width="100" height="34" rx="4"
|
||||
fill="#f5f5f5" stroke="#bbb" />
|
||||
<text x="480" y="212" text-anchor="middle" font-size="11">monitor</text>
|
||||
|
||||
<!-- monitor -> sndQ (sends PING) -->
|
||||
<line x1="430" y1="207" x2="260" y2="130"
|
||||
stroke="#555" stroke-dasharray="3,2" marker-end="url(#arr)" />
|
||||
<text x="370" y="180" font-size="9" fill="#555">PING</text>
|
||||
|
||||
<!-- monitor optional label -->
|
||||
<text x="540" y="210" font-size="9" fill="#bbb">optional</text>
|
||||
|
||||
<!-- ===== msgQ (server events to agent) ===== -->
|
||||
<rect x="250" y="310" width="200" height="38" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="350" y="327" text-anchor="middle" font-weight="bold">msgQ (optional)</text>
|
||||
<text x="350" y="341" text-anchor="middle" font-size="10">(TBQueue, server events)</text>
|
||||
|
||||
<!-- process -> msgQ (events with empty CorrId) -->
|
||||
<line x1="340" y1="270" x2="340" y2="308"
|
||||
<!-- process -> msgQ -->
|
||||
<line x1="250" y1="248" x2="250" y2="278"
|
||||
stroke="#333" marker-end="url(#arr)" />
|
||||
<text x="280" y="293" font-size="9" fill="#555">events (empty CorrId)</text>
|
||||
<text x="258" y="268" font-size="9" fill="#555">events</text>
|
||||
|
||||
<!-- msgQ -->
|
||||
<rect x="175" y="280" width="160" height="33" rx="4"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="255" y="296" text-anchor="middle" font-weight="bold">msgQ (optional)</text>
|
||||
<text x="255" y="308" text-anchor="middle" font-size="9">(TBQueue, server events)</text>
|
||||
|
||||
<!-- msgQ -> consumer -->
|
||||
<line x1="250" y1="329" x2="60" y2="329"
|
||||
<line x1="175" y1="296" x2="55" y2="296"
|
||||
stroke="#999" marker-end="url(#arr-g)" />
|
||||
<text x="100" y="323" font-size="9" fill="#999">to Agent / SMPClientAgent</text>
|
||||
<text x="65" y="290" font-size="9" fill="#999">to Agent / SMPClientAgent</text>
|
||||
|
||||
<!-- ===== LEGEND ===== -->
|
||||
<rect x="25" y="365" width="670" height="45" rx="4"
|
||||
<rect x="25" y="325" width="590" height="48" rx="4"
|
||||
fill="none" stroke="#ddd" />
|
||||
|
||||
<rect x="40" y="378" width="14" height="11" rx="2"
|
||||
<rect x="40" y="337" width="14" height="11" rx="2"
|
||||
fill="#e8f0fe" stroke="#4285f4" />
|
||||
<text x="60" y="388" font-size="10">thread</text>
|
||||
<text x="60" y="347" font-size="10">thread</text>
|
||||
|
||||
<rect x="130" y="378" width="14" height="11" rx="2"
|
||||
<rect x="130" y="337" width="14" height="11" rx="2"
|
||||
fill="#fef7e0" stroke="#f9ab00" />
|
||||
<text x="150" y="388" font-size="10">queue / state</text>
|
||||
<text x="150" y="347" font-size="10">queue / state</text>
|
||||
|
||||
<rect x="275" y="378" width="14" height="11" rx="2"
|
||||
<rect x="270" y="337" width="14" height="11" rx="2"
|
||||
fill="#f4f4f4" stroke="#999" />
|
||||
<text x="290" y="347" font-size="10">API entry point</text>
|
||||
|
||||
<rect x="410" y="337" width="14" height="11" rx="2"
|
||||
fill="#f5f5f5" stroke="#bbb" />
|
||||
<text x="295" y="388" font-size="10">optional</text>
|
||||
<text x="430" y="347" font-size="10">optional</text>
|
||||
|
||||
<text x="40" y="404" font-size="10" fill="#666">
|
||||
<text x="40" y="365" font-size="10" fill="#666">
|
||||
Solid arrows: TBQueue flow. Dashed: STM lookups / TMVar responses.
|
||||
</text>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.7 KiB |
@@ -10,13 +10,10 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="430" y="22" text-anchor="middle" font-size="15" font-weight="bold">SMP Router -- Component Topology</text>
|
||||
|
||||
<!-- ===== PER-CLIENT GROUP ===== -->
|
||||
<rect x="25" y="38" width="570" height="210" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
<text x="35" y="53" fill="#888" font-size="10">per client connection (raceAny_ -- any thread exit tears down connection)</text>
|
||||
<text x="35" y="53" fill="#888" font-size="10">per client connection (raceAny_: any exit tears down connection)</text>
|
||||
|
||||
<!-- receive -->
|
||||
<rect x="45" y="68" width="90" height="34" rx="4"
|
||||
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.0 KiB |
@@ -10,9 +10,6 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="310" y="22" text-anchor="middle" font-size="15" font-weight="bold">XFTP Client -- Component Topology</text>
|
||||
|
||||
<!-- ===== CLIENT WRAPPER ===== -->
|
||||
<rect x="120" y="40" width="380" height="130" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -10,9 +10,6 @@
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="370" y="22" text-anchor="middle" font-size="15" font-weight="bold">XFTP Router -- Component Topology</text>
|
||||
|
||||
<!-- ===== REQUEST HANDLING (no persistent threads) ===== -->
|
||||
<rect x="25" y="38" width="510" height="280" rx="6"
|
||||
fill="none" stroke="#888" stroke-dasharray="6,3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.4 KiB |
@@ -12,7 +12,7 @@ For deployment and configuration, see [docs/ROUTERS.md](../docs/ROUTERS.md). For
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Packet delivery flow
|
||||
|
||||
@@ -74,7 +74,7 @@ sequenceDiagram
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Data packet delivery flow
|
||||
|
||||
@@ -124,7 +124,7 @@ sequenceDiagram
|
||||
|
||||
### Component topology
|
||||
|
||||

|
||||

|
||||
|
||||
### Token registration and notification delivery
|
||||
|
||||
|
||||