// fetch returns the anchor files and subdirectories rooted at zdir func fetch(z *zookeeper.Conn, zdir string, children []string) (dirs map[string]struct{}, files map[circuit.WorkerID]*File, err error) { dirs = make(map[string]struct{}) files = make(map[circuit.WorkerID]*File) for _, name := range children { id, err := circuit.ParseWorkerID(name) if err != nil { // Node names that are not files are ok. // We treat them as subdirectories. dirs[name] = struct{}{} continue } znode := path.Join(zdir, name) data, _, err := z.Get(znode) if err != nil { // If this is a Zookeeper connection error, we should bail out log.Printf("Problem getting node `%s` from Zookeeper (%s)", znode, err) continue } zfile := &ZFile{} r := bytes.NewBufferString(data) if err := gob.NewDecoder(r).Decode(zfile); err != nil { log.Printf("anchor file cannot be parsed: (%s)", err) continue } if zfile.Addr.WorkerID() != id { log.Printf("anchor file name vs addr mismatch: %s vs %s\n", id, zfile.Addr.WorkerID()) continue } file := &File{owner: zfile.Addr} files[id] = file } return dirs, files, nil }
// CreateRecursive creates the directory leafPath and any parent subdirectories if necessary func CreateRecursive(z *zookeeper.Conn, leafPath string, aclv []zookeeper.ACL) error { leafPath = path.Clean(leafPath) if len(leafPath) == 0 || leafPath[0] != '/' { return errors.New("zookeeper util path syntax") } parts := strings.Split(leafPath, "/") if len(parts) < 1 { return errors.New("creating zookeeper root") } prefix := "/" for i := 0; i < len(parts); i++ { prefix = path.Join(prefix, parts[i]) if _, err := z.Create(prefix, "", 0, aclv); err != nil && !IsNodeExists(err) { return err } } return nil }