Skip to content

Latest commit

 

History

History
90 lines (65 loc) · 3.31 KB

File metadata and controls

90 lines (65 loc) · 3.31 KB

Mesh Protocol Specification

This document outlines the specifications for the Mesh protocol, enabling developers to implement compatible clients in other languages.

1. Service Discovery (Redis)

Mesh uses Redis as a centralized service registry.

1.1 Key Schema

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.

1.2 Value Schema

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
}

1.3 Mechanics

  • 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.

2. Transport Layer (HTTP/2)

Direct Peer-to-Peer communication happens over HTTP/2.

2.1 Connection

  • 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.

2.2 Stream Initiation

To open a channel to a service, the client initiates a new HTTP/2 stream with the following headers:

  • :method: POST
  • :scheme: http
  • :path: /channel
  • x-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

3. Message Protocol

Once the stream is established, meaningful messages are exchanged using a Length-Prefixed framing protocol over the raw stream body.

3.1 Framing

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.

3.2 Message Schema (JSON)

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
}

4. Implementation Checklist for New Clients

To implement a new Mesh client:

  1. Redis Connector: Implement logic to SET keys with TTL loop and SCAN/GET keys for discovery.
  2. HTTP/2 Server: Listen for incoming streams on /channel.
  3. HTTP/2 Client: Logic to connect to peers and initiate streams.
  4. Framer: Implement a reader that buffers bytes until it reads 4 bytes of length, then reads N bytes of payload.
  5. Loop: Run discovery and communication in parallel/async loops.