Files
x/router/plugin/grpc.go
T
ginuerzh 4443b0b964 fix(router): close httpLoader on shutdown, log parse errors, default nil logger
- Add missing httpLoader.Close() in localRouter.Close() to prevent
  resource leak
- Log parse errors from file/redis/http loaders instead of silently
  discarding them
- Add nil reader guards before calling parseRoutes in load()
- Default nil logger to xlogger.Nop() to prevent nil panics
- Use context.Background() instead of context.TODO() for root context
- Use strings.ReplaceAll instead of deprecated strings.Replace with -1
- Add doc comments to all exported symbols
- Add 27 unit tests + 1 benchmark
2026-05-25 23:03:19 +08:00

83 lines
1.6 KiB
Go

package router
import (
"context"
"io"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/router"
"github.com/go-gost/plugin/router/proto"
"github.com/go-gost/x/internal/plugin"
xrouter "github.com/go-gost/x/router"
"google.golang.org/grpc"
)
// grpcPlugin implements router.Router via a gRPC plugin connection.
type grpcPlugin struct {
conn grpc.ClientConnInterface
client proto.RouterClient
log logger.Logger
}
// NewGRPCPlugin creates an Router plugin based on gRPC.
func NewGRPCPlugin(name string, addr string, opts ...plugin.Option) router.Router {
var options plugin.Options
for _, opt := range opts {
opt(&options)
}
log := logger.Default().WithFields(map[string]any{
"kind": "router",
"router": name,
})
conn, err := plugin.NewGRPCConn(addr, &options)
if err != nil {
log.Error(err)
}
p := &grpcPlugin{
conn: conn,
log: log,
}
if conn != nil {
p.client = proto.NewRouterClient(conn)
}
return p
}
// GetRoute queries the gRPC plugin for the route to the given destination.
func (p *grpcPlugin) GetRoute(ctx context.Context, dst string, opts ...router.Option) *router.Route {
if p.client == nil {
return nil
}
var options router.Options
for _, opt := range opts {
opt(&options)
}
r, err := p.client.GetRoute(ctx,
&proto.GetRouteRequest{
Dst: dst,
Id: options.ID,
})
if err != nil {
p.log.Error(err)
return nil
}
return xrouter.ParseRoute(r.Dst, r.Gateway)
}
// Close closes the underlying gRPC connection.
func (p *grpcPlugin) Close() error {
if p.conn == nil {
return nil
}
if closer, ok := p.conn.(io.Closer); ok {
return closer.Close()
}
return nil
}