github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/zk/zookeeper.create.go (about)

     1  package zk
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/samuel/go-zookeeper/zk"
     9  	"github.com/sereiner/library/encoding"
    10  )
    11  
    12  //CreatePersistentNode 创建持久化的节点
    13  func (client *ZookeeperClient) CreatePersistentNode(path string, data string) (err error) {
    14  	if !client.isConnect {
    15  		err = ErrColientCouldNotConnect
    16  		return
    17  	}
    18  	//检查目录是否存在
    19  	if b, err := client.Exists(path); err != nil {
    20  		err = fmt.Errorf("create node %s fail(%t, err : %v)", path, b, err)
    21  		return err
    22  	} else if b {
    23  		return nil
    24  	}
    25  	if path == "/" {
    26  		return nil
    27  	}
    28  	//获取每级目录并检查是否存在,不存在则创建
    29  	paths := client.getPaths(path)
    30  	for i := 0; i < len(paths)-1; i++ {
    31  		b, err := client.Exists(paths[i])
    32  		if err != nil {
    33  			return err
    34  		}
    35  		if b {
    36  			continue
    37  		}
    38  		_, err = client.create(paths[i], "", int32(0), client.ACL)
    39  		if err != nil {
    40  			return err
    41  		}
    42  	}
    43  	//创建最后一级目录
    44  	_, err = client.create(path, data, int32(0), client.ACL)
    45  	if err != nil {
    46  		return
    47  	}
    48  	return nil
    49  }
    50  
    51  //CreateTempNode 创建临时节点
    52  func (client *ZookeeperClient) CreateTempNode(path string, data string) (err error) {
    53  	err = client.CreatePersistentNode(client.GetDir(path), "")
    54  	if err != nil {
    55  		return
    56  	}
    57  	_, err = client.create(path, data, int32(zk.FlagEphemeral), client.ACL)
    58  	return
    59  }
    60  
    61  //CreateSeqNode 创建临时节点
    62  func (client *ZookeeperClient) CreateSeqNode(path string, data string) (rpath string, err error) {
    63  	err = client.CreatePersistentNode(client.GetDir(path), "")
    64  	if err != nil {
    65  		return
    66  	}
    67  	rpath, err = client.create(path, data, int32(zk.FlagSequence)|int32(zk.FlagEphemeral), client.ACL)
    68  	return
    69  }
    70  
    71  type createType struct {
    72  	rpath string
    73  	err   error
    74  }
    75  
    76  func (client *ZookeeperClient) create(path string, data string, flags int32, acl []zk.ACL) (rpath string, err error) {
    77  	if !client.isConnect {
    78  		err = ErrColientCouldNotConnect
    79  		return
    80  	}
    81  	buff := encoding.Encode(data, "gbk")
    82  
    83  	// 开启一个协程,创建节点
    84  	ch := make(chan interface{}, 1)
    85  	go func(ch chan interface{}) {
    86  		data, err := client.conn.Create(path, buff, flags, acl)
    87  		if err != nil {
    88  			ch <- createType{err: err}
    89  		} else {
    90  			ch <- createType{rpath: data, err: err}
    91  		}
    92  	}(ch)
    93  
    94  	// 使用计时器判断创建节点是否超时
    95  	select {
    96  	case <-time.After(TIMEOUT):
    97  		err = fmt.Errorf("create node : %s timeout", path)
    98  		return
    99  	case data := <-ch:
   100  		err = data.(createType).err
   101  		if err != nil {
   102  			return
   103  		}
   104  		rpath = data.(createType).rpath
   105  		return
   106  	}
   107  }
   108  
   109  //getPaths 获取当前路径的所有子路径
   110  func (client *ZookeeperClient) getPaths(path string) []string {
   111  	nodes := strings.Split(path, "/")
   112  	len := len(nodes)
   113  	paths := make([]string, 0, len-1)
   114  	for i := 1; i < len; i++ {
   115  		npath := "/" + strings.Join(nodes[1:i+1], "/")
   116  		paths = append(paths, npath)
   117  	}
   118  	return paths
   119  }
   120  
   121  //GetDir 获取当前路径的目录
   122  func (client *ZookeeperClient) GetDir(path string) string {
   123  	paths := client.getPaths(path)
   124  	if len(paths) > 2 {
   125  		return paths[len(paths)-2]
   126  	}
   127  	return "/"
   128  }