func (c *Client) WatchPrefix(ctx context.Context, prefix string, opts ...easykv.WatchOption) (uint64, error) {
	var options easykv.WatchOptions
	for _, o := range opts {
		o(&options)
	}
	etcdctx, cancel := context.WithCancel(ctx)
	defer cancel()
	var err error
	rch := c.client.Watch(etcdctx, prefix, clientv3.WithPrefix())
	for wresp := range rch {
		if wresp.Err() != nil {
			return options.WaitIndex, wresp.Err()
		}
		for _, ev := range wresp.Events {
			for _, k := range options.Keys {
				if strings.HasPrefix(string(ev.Kv.Key), k) {
					return uint64(ev.Kv.Version), err
				}
			}
		}
	}
	if ctx.Err() == context.Canceled {
		return options.WaitIndex, easykv.ErrWatchCanceled
	}
	return 0, err
}
WatchPrefix watches a specific prefix for changes.
package etcdv3
import (
	"strings"
	"time"
	"context"
	"github.com/HeavyHorst/easykv"
	"go.etcd.io/etcd/clientv3"
	"go.etcd.io/etcd/pkg/transport"
)
type Client struct {
	client *clientv3.Client
}
func NewEtcdClient(machines []string, cert, key, caCert string, basicAuth bool, username string, password string) (*Client, error) {
	var cli *clientv3.Client
	cfg := clientv3.Config{
		Endpoints:   machines,
		DialTimeout: 5 * time.Second,
	}
	tlsInfo := &transport.TLSInfo{}
	if basicAuth {
		cfg.Username = username
		cfg.Password = password
	}
	tls := false
	if caCert != "" {
		tlsInfo.TrustedCAFile = caCert
		tls = true
	}
	if cert != "" && key != "" {
		tlsInfo.CertFile = cert
		tlsInfo.KeyFile = key
		tls = true
	}
	if tls {
		clientConf, err := tlsInfo.ClientConfig()
		if err != nil {
			return &Client{cli}, err
		}
		cfg.TLS = clientConf
	}
	cli, err := clientv3.New(cfg)
	if err != nil {
		return &Client{cli}, err
	}
	return &Client{cli}, nil
}
func (c *Client) Close() {
	if c.client != nil {
		c.client.Close()
	}
}
func (c *Client) GetValues(keys []string) (map[string]string, error) {
	vars := make(map[string]string)
	for _, key := range keys {
		ctx, cancel := context.WithTimeout(context.Background(), time.Duration(3)*time.Second)
		resp, err := c.client.Get(ctx, key, clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortDescend))
		cancel()
		if err != nil {
			return vars, err
		}
		for _, ev := range resp.Kvs {
			vars[string(ev.Key)] = string(ev.Value)
		}
	}
	return vars, nil
}