func NewEtcdV3Discovery(basePath string, servicePath string, etcdAddr []string, allowKeyNotFound bool, options *store.Config) (client.ServiceDiscovery, error) {
	kv, err := libkv.NewStore(estore.ETCDV3, etcdAddr, options)
	if err != nil {
		log.Infof("cannot create store: %v", err)
		return nil, err
	}
	if ev3, ok := kv.(*etcd.EtcdV3); ok {
		ev3.AllowKeyNotFound = allowKeyNotFound
	}
	return NewEtcdV3DiscoveryStore(basePath+"/"+servicePath, kv, allowKeyNotFound)
}
NewEtcdV3Discovery returns a new EtcdV3Discovery.
package client
import (
	"strings"
	"sync"
	"time"
	"github.com/rpcxio/libkv"
	"github.com/rpcxio/libkv/store"
	estore "github.com/rpcxio/rpcx-etcd/store"
	etcd "github.com/rpcxio/rpcx-etcd/store/etcdv3"
	"github.com/smallnest/rpcx/client"
	"github.com/smallnest/rpcx/log"
)
func init() {
	etcd.Register()
}
type EtcdV3Discovery struct {
	basePath string
	kv       store.Store
	pairsMu  sync.RWMutex
	pairs    []*client.KVPair
	chans    []chan []*client.KVPair
	mu       sync.Mutex
	RetriesAfterWatchFailed int
	filter           client.ServiceDiscoveryFilter
	AllowKeyNotFound bool
	stopCh chan struct{}
}