Documentation
¶
Index ¶
- Constants
- Variables
- func ClientDialOptions() []grpc.DialOption
- func NewExtension(opts ...ConfigOption) forge.Extension
- func NewExtensionWithConfig(config Config) forge.Extension
- type Config
- type ConfigOption
- func WithAddress(addr string) ConfigOption
- func WithClientAuth(enable bool) ConfigOption
- func WithConfig(config Config) ConfigOption
- func WithHealthCheck(enable bool) ConfigOption
- func WithMaxConcurrentStreams(maxStreams uint32) ConfigOption
- func WithMaxMessageSize(size int) ConfigOption
- func WithMetrics(enable bool) ConfigOption
- func WithReflection(enable bool) ConfigOption
- func WithRequireConfig(require bool) ConfigOption
- func WithService(desc *grpc.ServiceDesc, impl any) ConfigOption
- func WithServiceRegistrar(register ServiceRegistrar) ConfigOption
- func WithTLS(certFile, keyFile, caFile string) ConfigOption
- func WithTracing(enable bool) ConfigOption
- type Extension
- type GRPC
- type GRPCService
- func (s *GRPCService) AddStreamInterceptor(interceptor grpc.StreamServerInterceptor)
- func (s *GRPCService) AddUnaryInterceptor(interceptor grpc.UnaryServerInterceptor)
- func (s *GRPCService) GetServer() *grpc.Server
- func (s *GRPCService) GetServices() []ServiceInfo
- func (s *GRPCService) GetStats() ServerStats
- func (s *GRPCService) Health(ctx context.Context) error
- func (s *GRPCService) IsRunning() bool
- func (s *GRPCService) Name() string
- func (s *GRPCService) Ping(ctx context.Context) error
- func (s *GRPCService) RegisterHealthChecker(service string, checker HealthChecker)
- func (s *GRPCService) RegisterService(desc *grpc.ServiceDesc, impl any) error
- func (s *GRPCService) Server() GRPC
- func (s *GRPCService) Start(ctx context.Context) error
- func (s *GRPCService) Stop(ctx context.Context) error
- type HealthChecker
- type KeepaliveConfig
- type MethodInfo
- type ServerStats
- type ServiceInfo
- type ServiceRegistrar
Constants ¶
const (
// ServiceKey is the DI key for the gRPC service.
ServiceKey = "grpc"
)
DI container keys for gRPC extension services.
Variables ¶
var ( ErrNotStarted = errors.New("grpc: server not started") ErrAlreadyStarted = errors.New("grpc: server already started") ErrRegisterAfterStart = errors.New("grpc: services must be registered before Start") ErrInvalidService = errors.New("grpc: invalid service registration") ErrServiceNotFound = errors.New("grpc: service not found") ErrInvalidConfig = errors.New("grpc: invalid configuration") ErrStartFailed = errors.New("grpc: failed to start server") ErrStopFailed = errors.New("grpc: failed to stop server") ErrHealthCheckFailed = errors.New("grpc: health check failed") )
Common gRPC errors.
Functions ¶
func ClientDialOptions ¶ added in v1.12.9
func ClientDialOptions() []grpc.DialOption
ClientDialOptions returns dial options that trace outbound calls and carry the caller's trace context. It reads the OpenTelemetry globals when called, so call it after forge.New and keep the result.
func NewExtension ¶
func NewExtension(opts ...ConfigOption) forge.Extension
NewExtension creates a new gRPC extension.
func NewExtensionWithConfig ¶
NewExtensionWithConfig creates a new gRPC extension with a complete config.
Types ¶
type Config ¶
type Config struct {
// Server settings
Address string `json:"address" mapstructure:"address" yaml:"address"`
MaxRecvMsgSize int `json:"max_recv_msg_size" mapstructure:"max_recv_msg_size" yaml:"max_recv_msg_size"`
MaxSendMsgSize int `json:"max_send_msg_size" mapstructure:"max_send_msg_size" yaml:"max_send_msg_size"`
MaxConcurrentStreams uint32 `json:"max_concurrent_streams" mapstructure:"max_concurrent_streams" yaml:"max_concurrent_streams"`
ConnectionTimeout time.Duration `json:"connection_timeout" mapstructure:"connection_timeout" yaml:"connection_timeout"`
Keepalive KeepaliveConfig `json:"keepalive" mapstructure:"keepalive" yaml:"keepalive"`
// TLS/mTLS
EnableTLS bool `json:"enable_tls" mapstructure:"enable_tls" yaml:"enable_tls"`
TLSCertFile string `json:"tls_cert_file,omitempty" mapstructure:"tls_cert_file" yaml:"tls_cert_file,omitempty"`
TLSKeyFile string `json:"tls_key_file,omitempty" mapstructure:"tls_key_file" yaml:"tls_key_file,omitempty"`
TLSCAFile string `json:"tls_ca_file,omitempty" mapstructure:"tls_ca_file" yaml:"tls_ca_file,omitempty"`
ClientAuth bool `json:"client_auth" mapstructure:"client_auth" yaml:"client_auth"` // Require client cert
// Health checking
EnableHealthCheck bool `json:"enable_health_check" mapstructure:"enable_health_check" yaml:"enable_health_check"`
// Reflection
EnableReflection bool `json:"enable_reflection" mapstructure:"enable_reflection" yaml:"enable_reflection"`
// Observability
EnableMetrics bool `json:"enable_metrics" mapstructure:"enable_metrics" yaml:"enable_metrics"`
EnableTracing bool `json:"enable_tracing" mapstructure:"enable_tracing" yaml:"enable_tracing"`
EnableLogging bool `json:"enable_logging" mapstructure:"enable_logging" yaml:"enable_logging"`
// Services set up the server before it starts. Add them with WithService
// and WithServiceRegistrar. Only the extension applies them:
// NewGRPCService and NewGRPCServer ignore this field.
Services []ServiceRegistrar `json:"-" mapstructure:"-" yaml:"-"`
// Config loading flags
RequireConfig bool `json:"-" mapstructure:"-" yaml:"-"`
}
Config contains configuration for the gRPC extension.
type ConfigOption ¶
type ConfigOption func(*Config)
ConfigOption is a functional option for Config.
func WithAddress ¶
func WithAddress(addr string) ConfigOption
func WithClientAuth ¶
func WithClientAuth(enable bool) ConfigOption
func WithConfig ¶
func WithConfig(config Config) ConfigOption
WithConfig replaces the whole config, including any services earlier options added. Put WithService and WithServiceRegistrar after it.
func WithHealthCheck ¶
func WithHealthCheck(enable bool) ConfigOption
func WithMaxConcurrentStreams ¶
func WithMaxConcurrentStreams(maxStreams uint32) ConfigOption
func WithMaxMessageSize ¶
func WithMaxMessageSize(size int) ConfigOption
func WithMetrics ¶
func WithMetrics(enable bool) ConfigOption
func WithReflection ¶
func WithReflection(enable bool) ConfigOption
func WithRequireConfig ¶
func WithRequireConfig(require bool) ConfigOption
func WithService ¶ added in v1.12.9
func WithService(desc *grpc.ServiceDesc, impl any) ConfigOption
WithService registers a service on the extension's server before it starts. desc is the generated descriptor, such as pb.Greeter_ServiceDesc, and impl implements its server interface.
func WithServiceRegistrar ¶ added in v1.12.9
func WithServiceRegistrar(register ServiceRegistrar) ConfigOption
WithServiceRegistrar adds a function that sets up the extension's server before it starts. Use it when an implementation needs dependencies from the container, or to add interceptors and health checkers next to the service.
func WithTLS ¶
func WithTLS(certFile, keyFile, caFile string) ConfigOption
func WithTracing ¶
func WithTracing(enable bool) ConfigOption
type Extension ¶
type Extension struct {
*forge.BaseExtension
// contains filtered or unexported fields
}
Extension implements forge.Extension for gRPC functionality. The extension is now a lightweight facade that loads config and registers services.
func (*Extension) Register ¶
Register registers the gRPC extension with the app. This method now only loads configuration and registers service constructors.
type GRPC ¶
type GRPC interface {
// Service registration
RegisterService(desc *grpc.ServiceDesc, impl any) error
// Server management
Start(ctx context.Context, addr string) error
Stop(ctx context.Context) error
GracefulStop(ctx context.Context) error
// Interceptors
AddUnaryInterceptor(interceptor grpc.UnaryServerInterceptor)
AddStreamInterceptor(interceptor grpc.StreamServerInterceptor)
// Health checking
RegisterHealthChecker(service string, checker HealthChecker)
// Server info. GetServer is nil until Start, and registering a generated
// service on it once it serves crashes the process: use RegisterService
// before Start.
GetServer() *grpc.Server
IsRunning() bool
GetStats() ServerStats
GetServices() []ServiceInfo
// Health
Ping(ctx context.Context) error
}
GRPC represents a unified gRPC server interface.
type GRPCService ¶
type GRPCService struct {
// contains filtered or unexported fields
}
GRPCService wraps a GRPC server implementation and provides lifecycle management. It implements vessel's di.Service interface so Vessel can manage its lifecycle.
func NewGRPCService ¶
func NewGRPCService(config Config, logger forge.Logger, metrics forge.Metrics) (*GRPCService, error)
NewGRPCService creates a new gRPC service with the given configuration. This is the constructor that will be registered with the DI container.
func (*GRPCService) AddStreamInterceptor ¶
func (s *GRPCService) AddStreamInterceptor(interceptor grpc.StreamServerInterceptor)
func (*GRPCService) AddUnaryInterceptor ¶
func (s *GRPCService) AddUnaryInterceptor(interceptor grpc.UnaryServerInterceptor)
func (*GRPCService) GetServer ¶
func (s *GRPCService) GetServer() *grpc.Server
GetServer returns the underlying grpc.Server. It is nil until Start has built it, and registering a generated service on a serving server crashes the process. Use RegisterService before Start.
func (*GRPCService) GetServices ¶
func (s *GRPCService) GetServices() []ServiceInfo
func (*GRPCService) GetStats ¶
func (s *GRPCService) GetStats() ServerStats
func (*GRPCService) Health ¶
func (s *GRPCService) Health(ctx context.Context) error
Health checks if the gRPC service is healthy.
func (*GRPCService) IsRunning ¶
func (s *GRPCService) IsRunning() bool
func (*GRPCService) Name ¶
func (s *GRPCService) Name() string
Name returns the service name for Vessel's lifecycle management.
func (*GRPCService) RegisterHealthChecker ¶
func (s *GRPCService) RegisterHealthChecker(service string, checker HealthChecker)
func (*GRPCService) RegisterService ¶
func (s *GRPCService) RegisterService(desc *grpc.ServiceDesc, impl any) error
func (*GRPCService) Server ¶
func (s *GRPCService) Server() GRPC
Server returns the underlying gRPC server implementation.
func (*GRPCService) Start ¶
func (s *GRPCService) Start(ctx context.Context) error
Start starts the gRPC service. Vessel calls it the first time anything resolves the service. Under the extension it does nothing, because the extension starts the server at the end of app.Start, so services that other extensions and hooks register on the way still make it onto it.
type HealthChecker ¶
HealthChecker checks service health.
type KeepaliveConfig ¶
type KeepaliveConfig struct {
Time time.Duration `json:"time" mapstructure:"time" yaml:"time"`
Timeout time.Duration `json:"timeout" mapstructure:"timeout" yaml:"timeout"`
EnforcementPolicy bool `json:"enforcement_policy" mapstructure:"enforcement_policy" yaml:"enforcement_policy"`
MinTime time.Duration `json:"min_time" mapstructure:"min_time" yaml:"min_time"`
PermitWithoutStream bool `json:"permit_without_stream" mapstructure:"permit_without_stream" yaml:"permit_without_stream"`
}
KeepaliveConfig contains keepalive settings.
type MethodInfo ¶
type MethodInfo struct {
Name string
IsClientStream bool
IsServerStream bool
InputType string
OutputType string
}
MethodInfo contains method metadata.
type ServerStats ¶
type ServerStats struct {
StartTime int64
TotalConnections int64
ActiveStreams int64
RPCsStarted int64
RPCsSucceeded int64
RPCsFailed int64
}
ServerStats contains server statistics.
type ServiceInfo ¶
type ServiceInfo struct {
Name string
Methods []MethodInfo
Description string
}
ServiceInfo contains service metadata.
type ServiceRegistrar ¶ added in v1.12.9
ServiceRegistrar sets up the extension's server before it starts. It can register services, add interceptors and register health checkers. app is the app the extension is registered with, so an implementation can resolve what it needs from app.Container().
The extension calls each registrar once, in order, when it builds the server. That happens the first time anything resolves the gRPC service, which is no later than the extension's Start. A registrar that resolves GRPC or *GRPCService, directly or through another constructor, gets a circular dependency error.