This document outlines the specifications for the Mesh protocol, enabling developers to implement compatible clients in other languages.
Mesh uses Redis as a centralized service registry.
Services register themselves using the following key pattern:
mesh:service:{service_name}:{node_id}
service_name: The logical name of the service (e.g.,payment-service).node_id: A unique UUID v4 for the specific instance.
The value is a JSON string containing the node's connection details:
{
"id": "uuid-v4-string",
"service_name": "string",
"host": "ip-address-or-hostname",
"port": 1234, // Integer port number
"metadata": {} // Optional key-value pairs
}- Registration: SET the key with the JSON value and a TTL (Time To Live). Recommended TTL: 5-10 seconds.
- Heartbeat: Periodically refresh the TTL (e.g., every 2 seconds) to indicate liveness.
- Discovery: Scan keys matching
mesh:service:{target_service}:*to find available nodes.
Direct Peer-to-Peer communication happens over HTTP/2.
- Protocol: HTTP/2 (h2c or h2). Current implementations use plaintext (h2c) for local demos, but encryption (h2) is recommended for production.
- Connection Initiation: storage connections are persistent. A client opens a TCP connection to the target node's
host:port.
To open a channel to a service, the client initiates a new HTTP/2 stream with the following headers:
:method:POST:scheme:http:path:/channelx-service-name:{local_service_name}(Name of the service initiating the connection)x-session-id:{optional_session_id}x-service-name:{local_service_name}
Any additional headers sent during stream initiation or unary calls are exposed to the receiving handler as metadata.
The server accepts the stream by sending headers:
:status:200
Once the stream is established, meaningful messages are exchanged using a Length-Prefixed framing protocol over the raw stream body.
Every message sent on the stream MUST be prefixed with its length.
[Length (4 bytes)] + [Payload (N bytes)]
- Length: 4-byte big-endian unsigned integer (UInt32BE). Represents the number of bytes in the payload.
- Payload: The UTF-8 encoded JSON string of the message.
The payload is a JSON object with the following structure:
{
"function_name": "string", // Remote function or topic to invoke
"payload": "any", // The actual data (string, object, etc.)
"metadata": {} // Optional context
}To implement a new Mesh client:
- Redis Connector: Implement logic to
SETkeys with TTL loop andSCAN/GETkeys for discovery. - HTTP/2 Server: Listen for incoming streams on
/channel. - HTTP/2 Client: Logic to connect to peers and initiate streams.
- Framer: Implement a reader that buffers bytes until it reads 4 bytes of length, then reads
Nbytes of payload. - Loop: Run discovery and communication in parallel/async loops.