func createDashboardNode(conn zkhelper.Conn) error { // make sure root dir is exists rootDir := fmt.Sprintf("/zk/reborn/db_%s", globalEnv.ProductName()) zkhelper.CreateRecursive(conn, rootDir, "", 0, zkhelper.DefaultDirACLs()) coordPath := fmt.Sprintf("%s/dashboard", rootDir) // make sure we're the only one dashboard timeoutCh := time.After(60 * time.Second) for { if exists, _, ch, _ := conn.ExistsW(coordPath); exists { data, _, _ := conn.Get(coordPath) if checkDashboardAlive(data) { return errors.Errorf("dashboard already exists: %s", string(data)) } else { log.Warningf("dashboard %s exists in zk, wait it removed", data) select { case <-ch: case <-timeoutCh: return errors.Errorf("wait existed dashboard %s removed timeout", string(data)) } } } else { break } } content := fmt.Sprintf(`{"addr": "%v", "pid": %v}`, globalEnv.DashboardAddr(), os.Getpid()) pathCreated, err := conn.Create(coordPath, []byte(content), zk.FlagEphemeral, zkhelper.DefaultFileACLs()) log.Infof("dashboard node %s created, data %s, err %v", pathCreated, string(content), err) return errors.Trace(err) }