// Copyright 2015 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. package util import ( "encoding/json" "path" "github.com/juju/errors" "github.com/ngaut/go-zookeeper/zk" "github.com/ngaut/zkhelper" ) func getLeader(data []byte) (string, error) { m := struct { Addr string `json:"Addr"` }{} err := json.Unmarshal(data, &m) if err != nil { return "", errors.Trace(err) } return m.Addr, nil } // getLeaderPath gets the leader path in zookeeper. func getLeaderPath(rootPath string) string { return path.Join(rootPath, "leader") } // func checkLeaderExists(conn zkhelper.Conn) error { // // the leader node is not ephemeral, so we may meet no any tso server but leader node // // has the data for last closed tso server. // // TODO: check children in /candidates, if no child, we will treat it as no leader too. // return nil // } // GetLeaderAddr gets the leader tso address in zookeeper for outer use. func GetLeader(conn zkhelper.Conn, rootPath string) (string, error) { data, _, err := conn.Get(getLeaderPath(rootPath)) if err != nil { return "", errors.Trace(err) } // if err != checkLeaderExists(conn); err != nil { // return "", errors.Trace(err) // } return getLeader(data) } // GetWatchLeader gets the leader tso address in zookeeper and returns a watcher for leader change. func GetWatchLeader(conn zkhelper.Conn, rootPath string) (string, <-chan zk.Event, error) { data, _, watcher, err := conn.GetW(getLeaderPath(rootPath)) if err != nil { return "", nil, errors.Trace(err) } addr, err := getLeader(data) if err != nil { return "", nil, errors.Trace(err) } // if err != checkLeaderExists(conn); err != nil { // return "", errors.Trace(err) // } return addr, watcher, nil }