mirror of
https://github.com/hanzo-fi/go-libs.git
synced 2026-10-30 20:53:44 +00:00
124 lines
3.0 KiB
Go
124 lines
3.0 KiB
Go
package grpcserver
|
|
|
|
import (
|
|
"context"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
logging "github.com/hanzo-fi/go-libs/v5/pkg/observe/log"
|
|
"github.com/hanzo-fi/go-libs/v5/pkg/transport/serverport"
|
|
)
|
|
|
|
// Hook represents a lifecycle hook for the gRPC server.
|
|
// OnStart starts the server, OnStop shuts it down gracefully.
|
|
type Hook struct {
|
|
OnStart func(ctx context.Context) error
|
|
OnStop func(ctx context.Context) error
|
|
}
|
|
|
|
const serverPortDiscr = "grpc"
|
|
|
|
func ContextWithServerInfo(ctx context.Context) context.Context {
|
|
return serverport.ContextWithServerInfo(ctx, serverPortDiscr)
|
|
}
|
|
|
|
func startServer(ctx context.Context, s *serverport.Server, serverOptions []grpc.ServerOption, setupOptions []func(*grpc.Server)) (func(ctx context.Context) error, error) {
|
|
|
|
if err := s.Listen(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
grpcServer := grpc.NewServer(serverOptions...)
|
|
for _, option := range setupOptions {
|
|
option(grpcServer)
|
|
}
|
|
go func() {
|
|
if err := grpcServer.Serve(s.Listener); err != nil {
|
|
logging.FromContext(ctx).Errorf("failed to serve: %v", err)
|
|
}
|
|
}()
|
|
|
|
return func(ctx context.Context) error {
|
|
stopped := make(chan struct{})
|
|
go func() {
|
|
grpcServer.GracefulStop()
|
|
close(stopped)
|
|
}()
|
|
|
|
select {
|
|
case <-stopped:
|
|
return nil
|
|
case <-ctx.Done():
|
|
go grpcServer.Stop()
|
|
return ctx.Err()
|
|
}
|
|
}, nil
|
|
}
|
|
|
|
func Address(ctx context.Context) string {
|
|
return serverport.Address(ctx, serverPortDiscr)
|
|
}
|
|
|
|
type ServerOptions struct {
|
|
serverPortOptions []serverport.ServerOpts
|
|
grpcServerOpts []grpc.ServerOption
|
|
grpcSetupOpts []func(server *grpc.Server)
|
|
}
|
|
|
|
type ServerOptionModifier func(server *ServerOptions)
|
|
|
|
func WithServerPortOptions(opts ...serverport.ServerOpts) ServerOptionModifier {
|
|
return func(serverOptions *ServerOptions) {
|
|
serverOptions.serverPortOptions = append(serverOptions.serverPortOptions, opts...)
|
|
}
|
|
}
|
|
|
|
func WithGRPCServerOptions(opts ...grpc.ServerOption) ServerOptionModifier {
|
|
return func(serverOptions *ServerOptions) {
|
|
serverOptions.grpcServerOpts = append(serverOptions.grpcServerOpts, opts...)
|
|
}
|
|
}
|
|
|
|
func WithGRPCSetupOptions(opts ...func(server *grpc.Server)) ServerOptionModifier {
|
|
return func(serverOptions *ServerOptions) {
|
|
serverOptions.grpcSetupOpts = append(serverOptions.grpcSetupOpts, opts...)
|
|
}
|
|
}
|
|
|
|
func NewHook(serverOptionsModifiers ...ServerOptionModifier) Hook {
|
|
var (
|
|
close func(ctx context.Context) error
|
|
err error
|
|
)
|
|
|
|
options := &ServerOptions{}
|
|
for _, option := range serverOptionsModifiers {
|
|
option(options)
|
|
}
|
|
|
|
server := serverport.NewServer(serverPortDiscr, options.serverPortOptions...)
|
|
|
|
return Hook{
|
|
OnStart: func(ctx context.Context) error {
|
|
logging.FromContext(ctx).Infof("starting GRPC server")
|
|
close, err = startServer(
|
|
ctx,
|
|
server,
|
|
options.grpcServerOpts,
|
|
options.grpcSetupOpts,
|
|
)
|
|
return err
|
|
},
|
|
OnStop: func(ctx context.Context) error {
|
|
if close == nil {
|
|
return nil
|
|
}
|
|
logging.FromContext(ctx).Infof("Stop GRPC server")
|
|
defer func() {
|
|
logging.FromContext(ctx).Infof("GRPC server stopped")
|
|
}()
|
|
return close(ctx)
|
|
},
|
|
}
|
|
}
|