Documentation
¶
Overview ¶
Package fxgrpc provides a convenient way to create well behaved grpc servers and clients.
Example ¶
package main
import (
"context"
"fmt"
sconfig "github.com/exoscale/stelling/config"
"github.com/exoscale/stelling/fxgrpc"
"go.uber.org/fx"
"go.uber.org/fx/fxevent"
"go.uber.org/zap"
pb "google.golang.org/grpc/examples/route_guide/routeguide"
"google.golang.org/grpc/status"
)
type Config struct {
fxgrpc.Server
fxgrpc.Client
}
type RouteGuideServer struct {
pb.UnimplementedRouteGuideServer
}
func NewRouteGuideServer() pb.RouteGuideServer {
return &RouteGuideServer{}
}
func main() {
conf := &Config{}
args := []string{"grpc-test", "--server.address", "localhost:8080", "--client.endpoint", "localhost:8080", "--client.insecure-connection"}
if err := sconfig.Load(conf, args); err != nil {
panic(err)
}
opts := fx.Options(
// Suppressing fx logs to ensure deterministic output
fx.WithLogger(func() fxevent.Logger { return fxevent.NopLogger }),
fxgrpc.NewServerModule(conf),
fxgrpc.NewClientModule(conf),
fx.Provide(
// supplying a NopLogger to make output deterministic
// In practise you'd use fxlogging.NewModule to get a zap logger
// and replace the fxevent logger
zap.NewNop,
NewRouteGuideServer,
pb.NewRouteGuideClient,
),
fx.Invoke(
pb.RegisterRouteGuideServer,
// We explicitly need to invoke this, because ordering matters
fxgrpc.StartGrpcServer,
run,
),
)
if err := fx.ValidateApp(opts); err != nil {
panic(err)
}
fx.New(opts).Run()
}
func run(lc fx.Lifecycle, sd fx.Shutdowner, client pb.RouteGuideClient) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
go func() {
defer sd.Shutdown() //nolint:errcheck
_, err := client.GetFeature(
context.Background(),
&pb.Point{},
)
res, ok := status.FromError(err)
if !ok {
panic(fmt.Sprintln("could not extract grpc status code:", err))
}
fmt.Println("Endpoint returned status", res.String())
}()
return nil
},
})
}
Output: Endpoint returned status rpc error: code = Unimplemented desc = method GetFeature not implemented
Index ¶
- Constants
- func GetCertReloaderConfig(conf Config) *reloader.CertReloaderConfig
- func MakeClientTLS(c ClientConfig, logger *zap.Logger) (credentials.TransportCredentials, *reloader.CertReloader, error)
- func NewClientModule(conf ClientConfig) fx.Option
- func NewConnManagerModule(conf ConnManagerConfig) fx.Option
- func NewGrpcClient(conf ClientConfig, logger *zap.Logger, ui []*UnaryClientInterceptor, ...) (*grpc.ClientConn, error)
- func NewGrpcServer(p GrpcServerParams) (*grpc.Server, error)
- func NewNamedClientModule(name string, conf ClientConfig) fx.Option
- func NewServerModule(conf Config, sOpts ...serverModuleOption) fx.Option
- func ProvideGrpcClient(p GrpcClientParams) (grpc.ClientConnInterface, error)
- func SortInterceptors[T WeightedInterceptor](list []T) []T
- func StartGrpcServer(lc fx.Lifecycle, logger *zap.Logger, s *server)
- func StreamServerInterceptors(si []*StreamServerInterceptor) grpc.ServerOption
- func UnaryServerInterceptors(ui []*UnaryServerInterceptor) grpc.ServerOption
- func WithServerModuleName(name string) serverModuleOption
- func WithStreamClientInterceptors(si []*StreamClientInterceptor) grpc.DialOption
- func WithUnaryClientInterceptors(ui []*UnaryClientInterceptor) grpc.DialOption
- type Client
- type ClientConfig
- type Config
- type ConnManager
- type ConnManagerConfig
- type ConnManagerOpts
- type ConnManagerParams
- type GrpcClientParams
- type GrpcServerParams
- type Server
- type StreamClientInterceptor
- type StreamServerInterceptor
- type UnaryClientInterceptor
- type UnaryServerInterceptor
- type WeightedInterceptor
- type WeightedInterceptors
Examples ¶
Constants ¶
const Name = "proto"
Name is the name registered for the proto compressor.
Variables ¶
This section is empty.
Functions ¶
func GetCertReloaderConfig ¶
func GetCertReloaderConfig(conf Config) *reloader.CertReloaderConfig
func MakeClientTLS ¶
func MakeClientTLS(c ClientConfig, logger *zap.Logger) (credentials.TransportCredentials, *reloader.CertReloader, error)
func NewClientModule ¶
func NewClientModule(conf ClientConfig) fx.Option
NewClientModule Provides a grpc client
func NewConnManagerModule ¶
func NewConnManagerModule(conf ConnManagerConfig) fx.Option
func NewGrpcClient ¶
func NewGrpcClient(conf ClientConfig, logger *zap.Logger, ui []*UnaryClientInterceptor, si []*StreamClientInterceptor, handlers []stats.Handler, dOpts ...grpc.DialOption) (*grpc.ClientConn, error)
NewGrpcClient returns a grpc client connection that is configured with the same conventions as the fx module It is intended to be used for dynamically created, short lived, clients where using fx causes more troubles than benefits Because the client is assumed to be short lived, it will not reload TLS certificates
func NewGrpcServer ¶
func NewGrpcServer(p GrpcServerParams) (*grpc.Server, error)
func NewNamedClientModule ¶
func NewNamedClientModule(name string, conf ClientConfig) fx.Option
NewNamedClientModule Provides a named grpc client
func NewServerModule ¶
func ProvideGrpcClient ¶
func ProvideGrpcClient(p GrpcClientParams) (grpc.ClientConnInterface, error)
func SortInterceptors ¶
func SortInterceptors[T WeightedInterceptor](list []T) []T
SortInterceptors will order the slice of given interceptors and returns the ordered slice Items will be sorted in ascending weight Any nil items will be removed It is some sugar around sort.Sort to help with the type system checks The interceptor list should never be so large that the performance of this function matters
func StreamServerInterceptors ¶
func StreamServerInterceptors(si []*StreamServerInterceptor) grpc.ServerOption
func UnaryServerInterceptors ¶
func UnaryServerInterceptors(ui []*UnaryServerInterceptor) grpc.ServerOption
func WithServerModuleName ¶
func WithServerModuleName(name string) serverModuleOption
WithServerModuleName will annotate the outputs with the given name
func WithStreamClientInterceptors ¶
func WithStreamClientInterceptors(si []*StreamClientInterceptor) grpc.DialOption
func WithUnaryClientInterceptors ¶
func WithUnaryClientInterceptors(ui []*UnaryClientInterceptor) grpc.DialOption
Types ¶
type Client ¶
type Client struct {
// InsecureConnection indicates whether TLS needs to be disabled when connecting to the grpc server
InsecureConnection bool
// CertFile is the path to the pem encoded TLS certificate
CertFile string `validate:"omitempty,file"`
// KeyFile is the path to the pem encoded private key of the TLS certificate
KeyFile string `validate:"required_with=CertFile,omitempty,file"`
// RootCAFile is the path to a pem encoded CA bundle used to validate server connections
RootCAFile string `validate:"omitempty,file"`
// Endpoint is IP or hostname or scheme for the target gRPC server
Endpoint string `validate:"required"`
}
func (*Client) GrpcClientConfig ¶
func (*Client) MarshalLogObject ¶
func (c *Client) MarshalLogObject(enc zapcore.ObjectEncoder) error
type ClientConfig ¶
type ClientConfig interface {
GrpcClientConfig() *Client
}
type ConnManager ¶
type ConnManager struct {
// contains filtered or unexported fields
}
ConnManager is a cache of grpc.ClientConn's Users of the manager should leave the lifecycle of the underlying gRPC connections entirely up to the manager
func NewConnManager ¶
func NewConnManager(opts []grpc.DialOption) *ConnManager
func ProvideConnManager ¶
func ProvideConnManager(p ConnManagerParams) *ConnManager
func (*ConnManager) Get ¶
func (m *ConnManager) Get(address string) (*grpc.ClientConn, error)
type ConnManagerConfig ¶
type ConnManagerConfig interface {
ConnManagerConfig() *ConnManagerOpts
}
type ConnManagerOpts ¶
type ConnManagerOpts struct {
// InsecureConnection indicates whether TLS needs to be disabled when connecting to the grpc server
InsecureConnection bool
// CertFile is the path to the pem encoded TLS certificate
CertFile string `validate:"omitempty,file"`
// KeyFile is the path to the pem encoded private key of the TLS certificate
KeyFile string `validate:"required_with=CertFile,omitempty,file"`
// RootCAFile is the path to a pem encoded CA bundle used to validate server connections
RootCAFile string `validate:"omitempty,file"`
}
func (*ConnManagerOpts) ConnManagerConfig ¶
func (c *ConnManagerOpts) ConnManagerConfig() *ConnManagerOpts
type ConnManagerParams ¶
type ConnManagerParams struct {
fx.In
Lc fx.Lifecycle
Opts []grpc.DialOption `group:"grpc_client_options"`
Reloader *fxcert_reloader.CertReloader `optional:"true" name:"grpc_conn_manager"`
UnaryInterceptors []*UnaryClientInterceptor `group:"unary_client_interceptor"`
StreamInterceptors []*StreamClientInterceptor `group:"stream_client_interceptor"`
}
type GrpcClientParams ¶
type GrpcClientParams struct {
fx.In
Lc fx.Lifecycle
Conf ClientConfig
Logger *zap.Logger
StatsHandlers []stats.Handler `group:"client_stats_handler"`
UnaryInterceptors []*UnaryClientInterceptor `group:"unary_client_interceptor"`
StreamInterceptors []*StreamClientInterceptor `group:"stream_client_interceptor"`
ClientOpts []grpc.DialOption `group:"grpc_client_options"`
}
type GrpcServerParams ¶
type GrpcServerParams struct {
fx.In
Conf Config
StatsHandlers []stats.Handler `group:"server_stats_handler"`
UnaryInterceptors []*UnaryServerInterceptor `group:"unary_server_interceptor"`
StreamInterceptors []*StreamServerInterceptor `group:"stream_server_interceptor"`
Reloader *reloader.CertReloader `name:"grpc_server" optional:"true"`
ServerOpts []grpc.ServerOption `group:"grpc_server_options"`
}
type Server ¶
type Server struct {
// A systemd socket name. Takes precedence over Address
// In order to simplify, only systemd-activated socket with names are allowed, even if it is
// just one socket
SocketName string
// Address is the address+port the server will bind to, as passed to net.Listen
// If the Address starts with a / we will create unix domainsocket listener
Address string `default:"localhost:8080" validate:"tcp_addr|unix_addr"`
// TLS indicates whether the http server exposes with TLS
TLS bool
// CertFile is the path to the pem encoded TLS certificate
CertFile string `validate:"required_if=TLS true,omitempty,file"`
// KeyFile is the path to the pem encoded private key of the TLS certificate
KeyFile string `validate:"required_if=TLS true,omitempty,file"`
// ClientCAFile is the path to a pem encoded CA cert bundle used to validate clients
ClientCAFile string `validate:"excluded_without=TLS,omitempty,file"`
}
func (*Server) AsHttpConfig ¶
func (*Server) GrpcServerConfig ¶
func (*Server) MarshalLogObject ¶
func (s *Server) MarshalLogObject(enc zapcore.ObjectEncoder) error
type StreamClientInterceptor ¶
type StreamClientInterceptor struct {
Weight uint
Interceptor grpc.StreamClientInterceptor
}
StreamClientInterceptor wraps a grpc.StreamClientInterceptor with a weight that determines its position in the interceptor chain
func (*StreamClientInterceptor) GetWeight ¶
func (i *StreamClientInterceptor) GetWeight() uint
func (*StreamClientInterceptor) IsNil ¶
func (i *StreamClientInterceptor) IsNil() bool
type StreamServerInterceptor ¶
type StreamServerInterceptor struct {
Weight uint
Interceptor grpc.StreamServerInterceptor
}
StreamServerInterceptor wraps a grpc.StreamServerInterceptor with a weight that determines its position in the interceptor chain
func (*StreamServerInterceptor) GetWeight ¶
func (i *StreamServerInterceptor) GetWeight() uint
func (*StreamServerInterceptor) IsNil ¶
func (i *StreamServerInterceptor) IsNil() bool
type UnaryClientInterceptor ¶
type UnaryClientInterceptor struct {
Weight uint
Interceptor grpc.UnaryClientInterceptor
}
UnaryClientInterceptor wraps a grpc.UnaryClientInterceptor with a weight that determines its position in the interceptor chain
func (*UnaryClientInterceptor) GetWeight ¶
func (i *UnaryClientInterceptor) GetWeight() uint
func (*UnaryClientInterceptor) IsNil ¶
func (i *UnaryClientInterceptor) IsNil() bool
type UnaryServerInterceptor ¶
type UnaryServerInterceptor struct {
Weight uint
Interceptor grpc.UnaryServerInterceptor
}
UnaryServerInterceptor wraps a grpc.UnaryServerInterceptor with a weight that determines its position in the interceptor chain
func (*UnaryServerInterceptor) GetWeight ¶
func (i *UnaryServerInterceptor) GetWeight() uint
func (*UnaryServerInterceptor) IsNil ¶
func (i *UnaryServerInterceptor) IsNil() bool
type WeightedInterceptor ¶
type WeightedInterceptors ¶
type WeightedInterceptors []WeightedInterceptor
func (WeightedInterceptors) Len ¶
func (w WeightedInterceptors) Len() int
func (WeightedInterceptors) Less ¶
func (w WeightedInterceptors) Less(i, j int) bool
func (WeightedInterceptors) Swap ¶
func (w WeightedInterceptors) Swap(i, j int)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package health provides client-side health check capabilities for grpc servers.
|
Package health provides client-side health check capabilities for grpc servers. |
|
Package reflection provides reflection capabilities for grpc servers.
|
Package reflection provides reflection capabilities for grpc servers. |