func DeleteRecursive(zconn zookeeper.Conn, zkPath string, version int) error { // version: -1 delete any version of the node at path - only applies to the top node err := zconn.Delete(zkPath, int32(version)) if err == nil { return nil } if !ZkErrorEqual(err, zookeeper.ErrNotEmpty) { return err } // Remove the ability for other nodes to get created while we are trying to delete. // Otherwise, you can enter a race condition, or get starved out from deleting. _, err = zconn.SetACL(zkPath, zookeeper.WorldACL(zookeeper.PermAdmin|zookeeper.PermDelete|zookeeper.PermRead), int32(version)) if err != nil { return err } children, _, err := zconn.Children(zkPath) if err != nil { return err } for _, child := range children { err := DeleteRecursive(zconn, path.Join(zkPath, child), -1) if err != nil && !ZkErrorEqual(err, zookeeper.ErrNoNode) { return fmt.Errorf("zkutil: recursive delete failed: %v", err) } } err = zconn.Delete(zkPath, int32(version)) if err != nil && !ZkErrorEqual(err, zookeeper.ErrNotEmpty) { err = fmt.Errorf("zkutil: nodes getting recreated underneath delete (app race condition): %v", zkPath) } return err }