func (r *EtcdRegistry) UpdateNode(pctx context.Context, prefix string, status *Status) error {
	ctx, cancel := context.WithTimeout(pctx, r.reqTimeout)
	defer cancel()
	if exists, err := r.checkNodeExists(ctx, prefix, status.NodeID); err != nil {
		return errors.Trace(err)
	} else if !exists {
		log.Info("node dosen't exist, will create one", zap.String("NodeID", status.NodeID))
		return r.createNode(ctx, prefix, status)
	} else {
		return r.updateNode(ctx, prefix, status)
	}
}
UpdateNode update the node information.
package node
import (
	"context"
	"encoding/json"
	"path"
	"strings"
	"time"
	"github.com/pingcap/errors"
	"github.com/pingcap/log"
	"github.com/pingcap/tidb-tools/pkg/etcd"
	"go.etcd.io/etcd/clientv3"
	"go.uber.org/zap"
)
type EtcdRegistry struct {
	client     *etcd.Client
	reqTimeout time.Duration
}
func NewEtcdRegistry(cli *etcd.Client, reqTimeout time.Duration) *EtcdRegistry {
	return &EtcdRegistry{
		client:     cli,
		reqTimeout: reqTimeout,
	}
}
func (r *EtcdRegistry) Close() error {
	err := r.client.Close()
	return errors.Trace(err)
}
func (r *EtcdRegistry) prefixed(p ...string) string {
	return path.Join(p...)
}
func (r *EtcdRegistry) Node(pctx context.Context, prefix, nodeID string) (status *Status, revision int64, err error) {
	ctx, cancel := context.WithTimeout(pctx, r.reqTimeout)
	defer cancel()
	data, revision, err := r.client.Get(ctx, r.prefixed(prefix, nodeID))
	if err != nil {
		return nil, -1, errors.Trace(err)
	}
	if err = json.Unmarshal(data, &status); err != nil {
		return nil, -1, errors.Annotatef(err, "Invalid nodeID(%s)", nodeID)
	}
	return status, revision, nil
}
func (r *EtcdRegistry) Nodes(pctx context.Context, prefix string) (status []*Status, revision int64, err error) {
	ctx, cancel := context.WithTimeout(pctx, r.reqTimeout)
	defer cancel()
	resp, revision, err := r.client.List(ctx, r.prefixed(prefix))
	if err != nil {
		return nil, -1, errors.Trace(err)
	}
	status, err = NodesStatusFromEtcdNode(resp)
	if err != nil {
		return nil, -1, errors.Trace(err)
	}
	return status, revision, nil
}