cmd-stream-go allows execution of Commands on the server using the Command pattern.
It provides an extremely fast and flexible communication mechanism.
- Can work 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 (client streaming is not directly supported, but can also be implemented).
- Supports deadlines for sending Commands and Results.
- Supports timeouts.
- Supports reconnect feature.
- Supports keepalive feature.
- Can work with various serialization formats (here is an example using the Protobuf serializer).
- Has a modular architecture.
- cmd-stream-go
- Why cmd-stream-go?
- Brief cmd-stream-go Description
- Contents
- Command Pattern as an API Architecture Style
- Tests
- Benchmarks
- High-performance Communication Channel
- cmd-stream-go and RPC
- Network Protocols Support
- Client
- Server
- How To
- 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-communication-benchmarks
To build a high-performance communication channel between two services, consider the following guidelines:
- Use N connections, as several connections can transfer significantly more data than a single one. The optimal number, N, depends on your system and represents the point after which adding more connections does not improve 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.
Following these practices can significantly enhance throughput and reduce latency between your services.
If you're already using RPC, cmd-stream-go can enhance performance by providing a faster communication tool, here's an example.
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 can be safely used from multiple goroutines concurrently. It uses a single connection to send Commands and receive Results. Commands sent from a single goroutine are delivered to the server in order.
The server initiates the connection by sending ServerInfo to the client. The client uses this information to verify compatibility, such as ensuring both endpoints support the same set of Commands.
Each Command is executed by a single Invoker
(it should be thread-safe) in a
separete goroutine. Also a Command can send multiple Results back, all of which
will be delivered to the client in order, here's
an example.
There are the following cmd-stream-go submodules:
- base-go: Basic module, that contains the 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 execute 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.