func (lp *LongPool) Discard(conn net.Conn) error {
	c, ok := conn.(*longConn)
	if ok {
		return c.Conn.Close()
	}
	return conn.Close()
}
Discard implements the ConnPool interface.
package connpool
import (
	"context"
	"net"
	"reflect"
	"sync"
	"time"
	"github.com/cloudwego/kitex/pkg/connpool"
	"github.com/cloudwego/kitex/pkg/remote"
	"github.com/cloudwego/kitex/pkg/utils"
)
var (
	_ net.Conn            = &longConn{}
	_ remote.LongConnPool = &LongPool{}
)
type netAddr struct {
	network string
	address string
}
func (na netAddr) Network() string { return na.network }
func (na netAddr) String() string { return na.address }
type longConn struct {
	net.Conn
	sync.RWMutex
	deadline time.Time
}
func (c *longConn) Close() error {
	return nil
}
func (c *longConn) RawConn() net.Conn {
	return c.Conn
}
func (c *longConn) IsActive() bool {
	if conn, ok := c.Conn.(remote.IsActive); ok {
		if !conn.IsActive() {
			return false
		}
	}
	return time.Now().Before(c.deadline)
}
type peer struct {
	serviceName    string
	addr           net.Addr
	ring           *utils.Ring
	globalIdle     *utils.MaxCounter
	maxIdleTimeout time.Duration
}
func newPeer(
	serviceName string,
	addr net.Addr,
	maxIdle int,
	maxIdleTimeout time.Duration,
	globalIdle *utils.MaxCounter,
) *peer {
	return &peer{
		serviceName:    serviceName,
		addr:           addr,
		ring:           utils.NewRing(maxIdle),
		globalIdle:     globalIdle,
		maxIdleTimeout: maxIdleTimeout,
	}
}
func (p *peer) Reset(addr net.Addr) {
	p.addr = addr
	p.Close()
}
func (p *peer) Get(d remote.Dialer, timeout time.Duration, reporter Reporter) (net.Conn, error) {
	for {
		conn, _ := p.ring.Pop().(*longConn)
		if conn == nil {
			break
		}
		p.globalIdle.Dec()
		if conn.IsActive() {
			reporter.ReuseSucceed(Long, p.serviceName, p.addr)
			return conn, nil
		}
		_ = conn.Conn.Close()
	}
	conn, err := d.DialTimeout(p.addr.Network(), p.addr.String(), timeout)
	if err != nil {
		reporter.ConnFailed(Long, p.serviceName, p.addr)
		return nil, err
	}
	reporter.ConnSucceed(Long, p.serviceName, p.addr)
	return &longConn{Conn: conn, deadline: time.Now().Add(p.maxIdleTimeout)}, nil
}
func (p *peer) put(c *longConn) error {
	if !p.globalIdle.Inc() {
		return c.Conn.Close()
	}
	c.deadline = time.Now().Add(p.maxIdleTimeout)
	err := p.ring.Push(c)
	if err != nil {
		p.globalIdle.Dec()
		return c.Conn.Close()
	}
	return nil
}
func (p *peer) Close() {
	for {
		conn, _ := p.ring.Pop().(*longConn)
		if conn == nil {
			break
		}
		p.globalIdle.Dec()
		_ = conn.Conn.Close()
	}
}
type LongPool struct {
	reporter Reporter
	peerMap  sync.Map
	newPeer  func(net.Addr) *peer
}
func (lp *LongPool) getPeer(addr netAddr) *peer {
	p, ok := lp.peerMap.Load(addr)
	if ok {
		return p.(*peer)
	}
	p, _ = lp.peerMap.LoadOrStore(addr, lp.newPeer(addr))
	return p.(*peer)
}
func (lp *LongPool) Get(ctx context.Context, network, address string, opt *remote.ConnOption) (net.Conn, error) {
	addr := netAddr{network, address}
	p := lp.getPeer(addr)
	return p.Get(opt.Dialer, opt.ConnectTimeout, lp.reporter)
}
func (lp *LongPool) Put(conn net.Conn) error {
	c, ok := conn.(*longConn)
	if !ok {
		return conn.Close()
	}
	addr := conn.RemoteAddr()
	na := netAddr{addr.Network(), addr.String()}
	p, ok := lp.peerMap.Load(na)
	if ok {
		p.(*peer).put(c)
		return nil
	}
	return c.Conn.Close()
}