chore: stabilize lint and verify builds

This commit is contained in:
2026-02-06 11:51:32 +08:00
parent edede17880
commit 1782f64417
114 changed files with 3032 additions and 1345 deletions

View File

@@ -36,15 +36,16 @@ type Config struct {
ShutdownTimeoutSeconds uint
}
func (h *Config) Address() string {
if h.Port == 0 {
h.Port = 8081
func (cfg *Config) Address() string {
if cfg.Port == 0 {
cfg.Port = 8081
}
if h.Host == nil {
return fmt.Sprintf(":%d", h.Port)
if cfg.Host == nil {
return fmt.Sprintf(":%d", cfg.Port)
}
return fmt.Sprintf("%s:%d", *h.Host, h.Port)
return fmt.Sprintf("%s:%d", *cfg.Host, cfg.Port)
}
type Grpc struct {
@@ -56,45 +57,45 @@ type Grpc struct {
streamInterceptors []grpc.StreamServerInterceptor
}
func (g *Grpc) Init() error {
func (grpcServer *Grpc) Init() error {
// merge options and build interceptor chains if provided
var srvOpts []grpc.ServerOption
if len(g.unaryInterceptors) > 0 {
srvOpts = append(srvOpts, grpc.ChainUnaryInterceptor(g.unaryInterceptors...))
if len(grpcServer.unaryInterceptors) > 0 {
srvOpts = append(srvOpts, grpc.ChainUnaryInterceptor(grpcServer.unaryInterceptors...))
}
if len(g.streamInterceptors) > 0 {
srvOpts = append(srvOpts, grpc.ChainStreamInterceptor(g.streamInterceptors...))
if len(grpcServer.streamInterceptors) > 0 {
srvOpts = append(srvOpts, grpc.ChainStreamInterceptor(grpcServer.streamInterceptors...))
}
srvOpts = append(srvOpts, g.options...)
srvOpts = append(srvOpts, grpcServer.options...)
g.Server = grpc.NewServer(srvOpts...)
grpcServer.Server = grpc.NewServer(srvOpts...)
// optional reflection and health
if g.config.EnableReflection != nil && *g.config.EnableReflection {
reflection.Register(g.Server)
if grpcServer.config.EnableReflection != nil && *grpcServer.config.EnableReflection {
reflection.Register(grpcServer.Server)
}
if g.config.EnableHealth != nil && *g.config.EnableHealth {
if grpcServer.config.EnableHealth != nil && *grpcServer.config.EnableHealth {
hs := health.NewServer()
grpc_health_v1.RegisterHealthServer(g.Server, hs)
grpc_health_v1.RegisterHealthServer(grpcServer.Server, hs)
}
// graceful stop with timeout fallback to Stop()
container.AddCloseAble(func() {
timeout := g.config.ShutdownTimeoutSeconds
timeout := grpcServer.config.ShutdownTimeoutSeconds
if timeout == 0 {
timeout = 10
}
done := make(chan struct{})
go func() {
g.Server.GracefulStop()
grpcServer.Server.GracefulStop()
close(done)
}()
select {
case <-done:
// graceful stop finished
case <-time.After(time.Duration(timeout) * time.Second):
case <-time.After(time.Duration(int64(timeout)) * time.Second):
// timeout, force stop
g.Server.Stop()
grpcServer.Server.Stop()
}
})
@@ -102,44 +103,52 @@ func (g *Grpc) Init() error {
}
// Serve
func (g *Grpc) Serve() error {
if g.Server == nil {
if err := g.Init(); err != nil {
func (grpcServer *Grpc) Serve() error {
if grpcServer.Server == nil {
if err := grpcServer.Init(); err != nil {
return err
}
}
l, err := net.Listen("tcp", g.config.Address())
listener, err := net.Listen("tcp", grpcServer.config.Address())
if err != nil {
return err
return fmt.Errorf("listen grpc address: %w", err)
}
return g.Server.Serve(l)
if err := grpcServer.Server.Serve(listener); err != nil {
return fmt.Errorf("serve grpc listener: %w", err)
}
return nil
}
func (g *Grpc) ServeWithListener(ln net.Listener) error {
return g.Server.Serve(ln)
func (grpcServer *Grpc) ServeWithListener(listener net.Listener) error {
if err := grpcServer.Server.Serve(listener); err != nil {
return fmt.Errorf("serve grpc with listener: %w", err)
}
return nil
}
// UseOptions appends gRPC ServerOptions to be applied when constructing the server.
func (g *Grpc) UseOptions(opts ...grpc.ServerOption) {
g.options = append(g.options, opts...)
func (grpcServer *Grpc) UseOptions(opts ...grpc.ServerOption) {
grpcServer.options = append(grpcServer.options, opts...)
}
// UseUnaryInterceptors appends unary interceptors to be chained.
func (g *Grpc) UseUnaryInterceptors(inters ...grpc.UnaryServerInterceptor) {
g.unaryInterceptors = append(g.unaryInterceptors, inters...)
func (grpcServer *Grpc) UseUnaryInterceptors(inters ...grpc.UnaryServerInterceptor) {
grpcServer.unaryInterceptors = append(grpcServer.unaryInterceptors, inters...)
}
// UseStreamInterceptors appends stream interceptors to be chained.
func (g *Grpc) UseStreamInterceptors(inters ...grpc.StreamServerInterceptor) {
g.streamInterceptors = append(g.streamInterceptors, inters...)
func (grpcServer *Grpc) UseStreamInterceptors(inters ...grpc.StreamServerInterceptor) {
grpcServer.streamInterceptors = append(grpcServer.streamInterceptors, inters...)
}
// Reset clears all configured options and interceptors.
// Useful in tests to ensure isolation.
func (g *Grpc) Reset() {
g.options = nil
g.unaryInterceptors = nil
g.streamInterceptors = nil
func (grpcServer *Grpc) Reset() {
grpcServer.options = nil
grpcServer.unaryInterceptors = nil
grpcServer.streamInterceptors = nil
}

View File

@@ -1,18 +1,24 @@
package grpc
import (
"fmt"
"go.ipao.vip/atom/container"
"go.ipao.vip/atom/opt"
)
func Provide(opts ...opt.Option) error {
o := opt.New(opts...)
options := opt.New(opts...)
var config Config
if err := o.UnmarshalConfig(&config); err != nil {
return err
if err := options.UnmarshalConfig(&config); err != nil {
return fmt.Errorf("unmarshal grpc config: %w", err)
}
return container.Container.Provide(func() (*Grpc, error) {
if err := container.Container.Provide(func() (*Grpc, error) {
return &Grpc{config: &config}, nil
}, o.DiOptions()...)
}, options.DiOptions()...); err != nil {
return fmt.Errorf("provide grpc: %w", err)
}
return nil
}