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 }