func (p *connPool) Get(ctx context.Context, network, address string, opt *remote.ConnOption) (net.Conn, error) {
	v, ok := p.conns.Load(address)
	if ok {
		tr := v.(grpc.ClientTransport)
		conn, err := newClientConn(ctx, tr, address)
		if err != nil {
			p.conns.Delete(address)
			return nil, err
		}
		return conn, nil
	}
	tr, err, _ := p.sfg.Do(address, func() (i interface{}, e error) {
		conn, err := opt.Dialer.DialTimeout(network, address, opt.ConnectTimeout)
		if err != nil {
			return nil, err
		}
		tr, err := grpc.NewClientTransport(context.Background(), conn.(netpoll.Connection), func(r grpc.GoAwayReason) {
			p.conns.Delete(address)
		}, func() {
			p.conns.Delete(address)
		})
		if err != nil {
			return nil, err
		}
		p.conns.Store(address, tr)
		return tr, nil
	})
	if err != nil {
		return nil, err
	}
	conn, err := newClientConn(ctx, tr.(grpc.ClientTransport), address)
	if err != nil {
		p.conns.Delete(address)
		return nil, err
	}
	return conn, nil
}
Get pick or generate a net.Conn and return
package nphttp2
import (
	"context"
	"io"
	"net"
	"sync"
	"github.com/cloudwego/netpoll"
	"github.com/cloudwego/kitex/pkg/remote"
	"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/grpc"
	"golang.org/x/sync/singleflight"
)
func NewConnPool() remote.LongConnPool {
	return &connPool{}
}
type connPool struct {
	sfg   singleflight.Group
	conns sync.Map  
}
var _ remote.LongConnPool = (*connPool)(nil)