cmd-stream-go is a high-performance client-server library for Go, built around the Command Pattern. To learn how the Command Pattern can be used for networked communication, see this series of posts.
It provides an extremely fast and flexible communication mechanism.
- Works over TCP, TLS or mutual TLS.
- Has an asynchronous client that uses only one connection for both sending Commands and receiving Results.
- Supports the server streaming, i.e. a Command can send back multiple Results.
- Supports deadlines for sending Commands and Results.
- Provides reconnect and keepalive features.
- Supports the Circuit Breaker pattern.
- Has OpenTelemetry integration.
- Can work with various serialization formats (here is an example using the Protobuf serializer).
- Follows a modular design.
- cmd-stream-go
- Why cmd-stream-go?
- Overview
- Contents
- Tests
- Benchmarks
- How To
- Network Protocols Support
- Client
- Server
- High-performance Communication Channel
- cmd-stream-go and RPC
- Architecture
The cmd-stream-go module includes only a few integration tests, while each submodule (see the Architecture section) has approximately 90% test coverage.
github.com/ymz-ncnk/go-client-server-benchmarks
To get started, simply implement the Command Pattern and generate the serialization code. Explore the following resources for more details:
cmd-stream-go is built on top of Go's standard net
package and supports
connection-oriented protocols such as TCP, TLS, and mutual TLS (for client
authentication).
The client is asynchronous and safe for concurrent use by multiple goroutines. It uses a single connection to send Commands and receive Results. Commands sent from the same goroutine are delivered to the server in order.
The server initiates the connection by sending a ServerInfo
message to the
client. The client uses this information to verify compatibility, for example,
ensuring that both endpoints support the same set of Commands.
Each Command is executed by a single Invoker
in a separate goroutine. A
Command can also send multiple Results back to the client, all of which are
delivered in order. Here's
an example.
To build a high-performance communication channel between two services, consider the following guidelines:
- Use N connections, as multiple connections can transfer significantly more data than a single one. The optimal value of N depends on your system and represents the point beyond which adding more connections no longer improves performance.
- To minimize latency, open all available connections at the start rather than creating new ones on demand.
- Keep connections alive to avoid the overhead of frequent connection setup and teardown.
These practices, implemented via the ClientGroup
, can significantly enhance
throughput and reduce latency between your services.
Already using RPC? cmd-stream-go can improve performance by providing a more efficient communication layer. Example here.
There are the following cmd-stream-go submodules:
- core-go: The core module that includes client and server definitions.
- delegate-go: The client delegates all communication-related tasks to its delegate, the server follows the same approach. The connection is also initialized at this level.
- handler-go: The server delegate uses a handler to receive and process Commands.
- transport-go: Resposible for Commands/Results delivery.
cmd-stream-go was designed in such a way that you can easily replace any part of it.