You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.1 KiB

  1. // Copyright 2015 PingCAP, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package util
  14. import (
  15. "encoding/json"
  16. "path"
  17. "github.com/juju/errors"
  18. "github.com/ngaut/go-zookeeper/zk"
  19. "github.com/ngaut/zkhelper"
  20. )
  21. func getLeader(data []byte) (string, error) {
  22. m := struct {
  23. Addr string `json:"Addr"`
  24. }{}
  25. err := json.Unmarshal(data, &m)
  26. if err != nil {
  27. return "", errors.Trace(err)
  28. }
  29. return m.Addr, nil
  30. }
  31. // getLeaderPath gets the leader path in zookeeper.
  32. func getLeaderPath(rootPath string) string {
  33. return path.Join(rootPath, "leader")
  34. }
  35. // func checkLeaderExists(conn zkhelper.Conn) error {
  36. // // the leader node is not ephemeral, so we may meet no any tso server but leader node
  37. // // has the data for last closed tso server.
  38. // // TODO: check children in /candidates, if no child, we will treat it as no leader too.
  39. // return nil
  40. // }
  41. // GetLeaderAddr gets the leader tso address in zookeeper for outer use.
  42. func GetLeader(conn zkhelper.Conn, rootPath string) (string, error) {
  43. data, _, err := conn.Get(getLeaderPath(rootPath))
  44. if err != nil {
  45. return "", errors.Trace(err)
  46. }
  47. // if err != checkLeaderExists(conn); err != nil {
  48. // return "", errors.Trace(err)
  49. // }
  50. return getLeader(data)
  51. }
  52. // GetWatchLeader gets the leader tso address in zookeeper and returns a watcher for leader change.
  53. func GetWatchLeader(conn zkhelper.Conn, rootPath string) (string, <-chan zk.Event, error) {
  54. data, _, watcher, err := conn.GetW(getLeaderPath(rootPath))
  55. if err != nil {
  56. return "", nil, errors.Trace(err)
  57. }
  58. addr, err := getLeader(data)
  59. if err != nil {
  60. return "", nil, errors.Trace(err)
  61. }
  62. // if err != checkLeaderExists(conn); err != nil {
  63. // return "", errors.Trace(err)
  64. // }
  65. return addr, watcher, nil
  66. }