func (sg *ServerGroup) RemoveServer(coordConn zkhelper.Conn, addr string) error { coordPath := fmt.Sprintf("/zk/reborn/db_%s/servers/group_%d/%s", sg.ProductName, sg.Id, addr) data, _, err := coordConn.Get(coordPath) if err != nil { return errors.Trace(err) } var s Server err = json.Unmarshal(data, &s) if err != nil { return errors.Trace(err) } log.Info(s) if s.Type == SERVER_TYPE_MASTER { return errors.New("cannot remove master, use promote first") } err = coordConn.Delete(coordPath, -1) if err != nil { return errors.Trace(err) } // update server list for i := 0; i < len(sg.Servers); i++ { if sg.Servers[i].Addr == s.Addr { sg.Servers = append(sg.Servers[:i], sg.Servers[i+1:]...) break } } // remove slave won't need proxy confirm err = NewAction(coordConn, sg.ProductName, ACTION_TYPE_SERVER_GROUP_CHANGED, sg, "", false) return errors.Trace(err) }
func GetServer(zkConn zkhelper.Conn, zkPath string) (*Server, error) { data, _, err := zkConn.Get(zkPath) if err != nil { return nil, errors.Trace(err) } srv := Server{} if err := json.Unmarshal(data, &srv); err != nil { return nil, errors.Trace(err) } return &srv, nil }
func GetActionObject(zkConn zkhelper.Conn, productName string, seq int64, act interface{}) error { data, _, err := zkConn.Get(path.Join(GetWatchActionPath(productName), "action_"+fmt.Sprintf("%0.10d", seq))) if err != nil { return errors.Trace(err) } if err := json.Unmarshal(data, act); err != nil { return errors.Trace(err) } return nil }
func ActionGC(zkConn zkhelper.Conn, productName string, gcType int, keep int) error { prefix := GetWatchActionPath(productName) exists, err := zkhelper.NodeExists(zkConn, prefix) if err != nil { return errors.Trace(err) } if !exists { // if action path not exists just return nil return nil } actions, _, err := zkConn.Children(prefix) if err != nil { return errors.Trace(err) } var act Action currentTs := time.Now().Unix() if gcType == GC_TYPE_N { sort.Strings(actions) if len(actions) <= keep { return nil } for _, action := range actions[:len(actions)-keep] { if err := zkhelper.DeleteRecursive(zkConn, path.Join(prefix, action), -1); err != nil { return errors.Trace(err) } } } else if gcType == GC_TYPE_SEC { secs := keep for _, action := range actions { b, _, err := zkConn.Get(path.Join(prefix, action)) if err != nil { return errors.Trace(err) } if err := json.Unmarshal(b, &act); err != nil { return errors.Trace(err) } log.Info(action, act.Ts) ts, _ := strconv.ParseInt(act.Ts, 10, 64) if currentTs-ts > int64(secs) { if err := zkConn.Delete(path.Join(prefix, action), -1); err != nil { return errors.Trace(err) } } } } 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) }
func GetActionObject(zkConn zkhelper.Conn, productName string, seq int64, act interface{}, provider string) error { data, _, err := zkConn.Get(path.Join(GetWatchActionPath(productName), zkConn.Seq2Str(seq))) if err != nil { return errors.Trace(err) } if err := json.Unmarshal(data, act); err != nil { return errors.Trace(err) } return nil }
func loadTimestamp(conn zkhelper.Conn, rootPath string) (int64, error) { data, _, err := conn.Get(getTimestampPath(rootPath)) if zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return 0, zk.ErrNoNode } else if err != nil { return 0, errors.Trace(err) } else if len(data) != 8 { return 0, errors.Errorf("invalid timestamp data, must 8 bytes, but %d", len(data)) } return int64(binary.BigEndian.Uint64(data)), nil }
func GetSlot(zkConn zkhelper.Conn, productName string, id int) (*Slot, error) { zkPath := GetSlotPath(productName, id) data, _, err := zkConn.Get(zkPath) if err != nil { return nil, err } slot := Slot{} if err := json.Unmarshal(data, &slot); err != nil { return nil, err } return &slot, nil }
func GetActionWithSeq(zkConn zkhelper.Conn, productName string, seq int64) (*Action, error) { var act Action data, _, err := zkConn.Get(path.Join(GetWatchActionPath(productName), "action_"+fmt.Sprintf("%0.10d", seq))) if err != nil { return nil, errors.Trace(err) } if err := json.Unmarshal(data, &act); err != nil { return nil, errors.Trace(err) } return &act, nil }
func GetProxyInfo(zkConn zkhelper.Conn, productName string, proxyName string) (*ProxyInfo, error) { var pi ProxyInfo data, _, err := zkConn.Get(path.Join(GetProxyPath(productName), proxyName)) if err != nil { return nil, errors.Trace(err) } if err := json.Unmarshal(data, &pi); err != nil { return nil, errors.Trace(err) } return &pi, nil }
func GetActionWithSeq(zkConn zkhelper.Conn, productName string, seq int64, provider string) (*Action, error) { var act Action data, _, err := zkConn.Get(path.Join(GetWatchActionPath(productName), zkConn.Seq2Str(seq))) if err != nil { return nil, errors.Trace(err) } if err := json.Unmarshal(data, &act); err != nil { return nil, errors.Trace(err) } return &act, nil }
func GetSlot(coordConn zkhelper.Conn, productName string, id int) (*Slot, error) { coordPath := GetSlotPath(productName, id) data, _, err := coordConn.Get(coordPath) if err != nil { return nil, err } var slot Slot if err := json.Unmarshal(data, &slot); err != nil { return nil, err } return &slot, nil }
func Slots(coordConn zkhelper.Conn, productName string) ([]*Slot, error) { coordPath := GetSlotBasePath(productName) children, _, err := coordConn.Children(coordPath) if err != nil { return nil, errors.Trace(err) } var slots []*Slot for _, p := range children { data, _, err := coordConn.Get(path.Join(coordPath, p)) if err != nil { return nil, errors.Trace(err) } slot := &Slot{} if err := json.Unmarshal(data, &slot); err != nil { return nil, errors.Trace(err) } slots = append(slots, slot) } return slots, nil }
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) }