Documentation
¶
Overview ¶
Package commongrpc provides helpers for creating and managing gRPC clients with support for connection pooling, telemetry instrumentation, keepalive configuration, and secure or insecure transport credentials (including mTLS).
It is designed to integrate with the common configuration model (commoncfg), connection pooling (grpcpool), and OpenTelemetry stats handlers (otlp).
Typical usage:
cfg := &commoncfg.GRPCClient{
Address: "localhost:50051",
Pool: commoncfg.GRPCPool{
InitialCapacity: 2,
MaxCapacity: 10,
},
Attributes: commoncfg.GRPCKeepalive{
KeepaliveTime: 10 * time.Second,
KeepaliveTimeout: 5 * time.Second,
},
SecretRef: &commoncfg.SecretRef{
Type: commoncfg.MTLSSecretType,
MTLS: commoncfg.MTLSSecret{ /* paths to certs */ },
},
}
// Using a pooled client
myClient := NewMyServiceClient()
if err := commongrpc.NewPooledClient(myClient, cfg); err != nil {
log.Fatalf("failed to init client: %v", err)
}
// Or using a single client connection
conn, err := commongrpc.NewClient(cfg)
if err != nil {
log.Fatalf("failed to dial: %v", err)
}
defer conn.Close()
Package commongrpc provides helpers for creating and managing gRPC clients with support for connection pooling, telemetry, and secure mTLS credential management.
One of the core features of this package is the ability to automatically refresh gRPC client connections when underlying TLS certificates or keys are updated on disk. This enables long-lived clients to handle certificate rotation without downtime.
Typical usage:
cfg := &commoncfg.GRPCClient{
Address: "my-grpc-server:443",
SecretRef: &commoncfg.SecretRef{
.....
},
}
client, err := commongrpc.NewDynamicClientConn(cfg, 2*time.Second)
if err != nil {
log.Fatalf("failed to create grpc client: %v", err)
}
defer client.Close()
grpcConn := client.ClientConn
myService := pb.NewMyServiceClient(grpcConn)
Index ¶
- Variables
- func NewClient(cfg *commoncfg.GRPCClient, dialOptions ...grpc.DialOption) (*grpc.ClientConn, error)
- func NewPooledClient(client PooledClient, cfg *commoncfg.GRPCClient, dialOptions ...grpc.DialOption) error
- func NewServer(ctx context.Context, cfg *commoncfg.GRPCServer, ...) *grpc.Server
- type DynamicClientConn
- type PooledClient
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmptyAddress is returned when the gRPC client configuration // does not specify a target address. ErrEmptyAddress = errors.New("grpc address is empty") // ErrUnsupportedSecretType is returned when a provided SecretRef // type is not supported for creating transport credentials. ErrUnsupportedSecretType = errors.New("unsupported secret type") )
Functions ¶
func NewClient ¶
func NewClient(cfg *commoncfg.GRPCClient, dialOptions ...grpc.DialOption) (*grpc.ClientConn, error)
NewClient creates a single gRPC client connection without pooling. It configures transport credentials, keepalive parameters, telemetry stats handlers, and applies any custom dial options.
Returns an error if the configuration is invalid or the connection fails.
Example:
conn, err := commongrpc.NewClient(cfg, grpc.WithBlock())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
func NewPooledClient ¶
func NewPooledClient(client PooledClient, cfg *commoncfg.GRPCClient, dialOptions ...grpc.DialOption) error
NewPooledClient initializes a pooled gRPC client based on the provided configuration. It applies transport security, keepalive parameters, OpenTelemetry stats handlers, and any custom dial options.
The client must implement the PooledClient interface to accept the created pool. The function returns an error if the configuration is invalid or if the pool cannot be created.
Example:
err := commongrpc.NewPooledClient(myClient, cfg,
grpc.WithBlock(),
)
func NewServer ¶
func NewServer(ctx context.Context, cfg *commoncfg.GRPCServer, serverOptions ...grpc.ServerOption) *grpc.Server
NewServer creates and configures a new gRPC server instance.
It applies keepalive enforcement and server parameters, maximum receive message size, and OpenTelemetry stats handlers. Additional grpc.ServerOption values can be provided.
If reflection is enabled in the config, the server will register the reflection service. If health checks are enabled, the server will register the gRPC health service.
Parameters:
- ctx: Context for logging and server setup
- cfg: Pointer to GRPCServer configuration
- serverOptions: Additional grpc.ServerOption values
Returns:
- *grpc.Server: The configured gRPC server instance
Types ¶
type DynamicClientConn ¶ added in v1.4.5
type DynamicClientConn struct {
*grpc.ClientConn
// contains filtered or unexported fields
}
DynamicClientConn represents a gRPC client connection that automatically refreshes itself when TLS certificate or key files change on disk.
This is particularly useful for setups where mTLS secrets are rotated frequently (e.g., by a secret manager or service mesh) and the client must always maintain a valid secure connection.
DynamicClientConn uses fsnotify to watch for file changes in the configured certificate/key/CA paths. When changes are detected, the client connection is torn down and recreated with the latest credentials.
func NewDynamicClientConn ¶ added in v1.4.5
func NewDynamicClientConn(cfg *commoncfg.GRPCClient, throttleInterval time.Duration, dialOptions ...grpc.DialOption) (*DynamicClientConn, error)
NewDynamicClientConn creates a new DynamicClientConn for the given gRPC client configuration. If a SecretRef is configured, the client will automatically watch the certificate, key, and CA file paths for changes. When a change is detected, the gRPC connection is refreshed in place with the latest credentials.
The throttleInterval parameter defines how frequently refresh events can be triggered. For example, a throttle interval of 2 seconds ensures that multiple rapid file system events (e.g., a cert + key update) result in only one reconnection attempt.
If no SecretRef is provided, the client behaves like a normal static gRPC client connection.
Example:
client, err := commongrpc.NewDynamicClientConn(cfg, 2*time.Second)
if err != nil {
return err
}
defer client.Close()
func (*DynamicClientConn) Close ¶ added in v1.4.5
func (dcc *DynamicClientConn) Close() error
Close stops the file watcher (if active) and closes the underlying gRPC client connection. After calling Close, the DynamicClientConn must not be reused.
func (*DynamicClientConn) HasClientConn ¶ added in v1.5.2
func (dcc *DynamicClientConn) HasClientConn() bool
HasClientConn returns true if the underlying ClientConn is non-nil. It acquires a read (shared) lock so that concurrent readers can check safely.
func (*DynamicClientConn) IsClientConnNil ¶ added in v1.5.2
func (dcc *DynamicClientConn) IsClientConnNil() bool
IsClientConnNil returns true if the underlying ClientConn is nil. It acquires a read (shared) lock so that concurrent readers can check safely.
type PooledClient ¶
PooledClient is an interface that clients must implement to support connection pooling. The SetPool method is called by NewPooledClient with a configured grpcpool.Pool.