func ServerGroups(zkConn zkhelper.Conn, productName string) ([]ServerGroup, error) { var ret []ServerGroup root := fmt.Sprintf("/zk/codis/db_%s/servers", productName) groups, _, err := zkConn.Children(root) if err != nil { return nil, errors.Trace(err) } // Buggy :X //zkhelper.ChildrenRecursive(*zkConn, root) for _, group := range groups { // parse group_1 => 1 groupId, err := strconv.Atoi(strings.Split(group, "_")[1]) if err != nil { return nil, errors.Trace(err) } g, err := GetGroup(zkConn, productName, groupId) if err != nil { return nil, errors.Trace(err) } ret = append(ret, *g) } return ret, nil }
func ServerGroups(coordConn zkhelper.Conn, productName string) ([]*ServerGroup, error) { var ret []*ServerGroup root := fmt.Sprintf("/zk/reborn/db_%s/servers", productName) groups, _, err := coordConn.Children(root) // if ErrNoNode, we may return an empty slice like ProxyList if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return nil, errors.Trace(err) } // Buggy :X //zkhelper.ChildrenRecursive(*coordConn, root) for _, group := range groups { // parse group_1 => 1 groupId, err := strconv.Atoi(strings.Split(group, "_")[1]) if err != nil { return nil, errors.Trace(err) } g, err := GetGroup(coordConn, productName, groupId) if err != nil { return nil, errors.Trace(err) } ret = append(ret, g) } return ret, nil }
func WaitForReceiverWithTimeout(zkConn zkhelper.Conn, productName string, actionZkPath string, proxies []ProxyInfo, timeoutInMs int) error { if len(proxies) == 0 { return nil } times := 0 proxyIds := make(map[string]struct{}) var offlineProxyIds []string for _, p := range proxies { proxyIds[p.Id] = struct{}{} } checkTimes := timeoutInMs / 500 // check every 500ms for times < checkTimes { if times >= 6 && (times*500)%1000 == 0 { log.Warning("abnormal waiting time for receivers", actionZkPath, offlineProxyIds) } // get confirm ids nodes, _, err := zkConn.Children(actionZkPath) if err != nil { return errors.Trace(err) } confirmIds := make(map[string]struct{}) for _, node := range nodes { id := path.Base(node) confirmIds[id] = struct{}{} } if len(confirmIds) != 0 { match := true // check if all proxy have responsed var notMatchList []string for id, _ := range proxyIds { // if proxy id not in confirm ids, means someone didn't response if _, ok := confirmIds[id]; !ok { match = false notMatchList = append(notMatchList, id) } } if match { return nil } offlineProxyIds = notMatchList } times += 1 time.Sleep(500 * time.Millisecond) } if len(offlineProxyIds) > 0 { log.Error("proxies didn't responed: ", offlineProxyIds) } // set offline proxies for _, id := range offlineProxyIds { log.Errorf("mark proxy %s to PROXY_STATE_MARK_OFFLINE", id) if err := SetProxyStatus(zkConn, productName, id, PROXY_STATE_MARK_OFFLINE); err != nil { return errors.Trace(err) } } return errors.Trace(ErrReceiverTimeout) }
func GetActionSeqList(zkConn zkhelper.Conn, productName string) ([]int, error) { nodes, _, err := zkConn.Children(GetWatchActionPath(productName)) if err != nil { return nil, errors.Trace(err) } return ExtraSeqList(nodes) }
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 }
func WaitForReceiver(zkConn zkhelper.Conn, productName string, actionZkPath string, proxies []ProxyInfo) error { if len(proxies) == 0 { return nil } times := 0 var proxyIds []string var offlineProxyIds []string for _, p := range proxies { proxyIds = append(proxyIds, p.Id) } sort.Strings(proxyIds) // check every 500ms for times < 60 { if times >= 6 && (times*500)%1000 == 0 { log.Warning("abnormal waiting time for receivers", actionZkPath) } nodes, _, err := zkConn.Children(actionZkPath) if err != nil { return errors.Trace(err) } var confirmIds []string for _, node := range nodes { id := path.Base(node) confirmIds = append(confirmIds, id) } if len(confirmIds) != 0 { sort.Strings(confirmIds) if utils.Strings(proxyIds).Eq(confirmIds) { return nil } offlineProxyIds = proxyIds[len(confirmIds)-1:] } times += 1 time.Sleep(500 * time.Millisecond) } if len(offlineProxyIds) > 0 { log.Error("proxies didn't responed: ", offlineProxyIds) } // set offline proxies for _, id := range offlineProxyIds { log.Errorf("mark proxy %s to PROXY_STATE_MARK_OFFLINE", id) if err := SetProxyStatus(zkConn, productName, id, PROXY_STATE_MARK_OFFLINE); err != nil { return err } } return ErrReceiverTimeout }
func GetFenceProxyMap(zkConn zkhelper.Conn, productName string) (map[string]bool, error) { children, _, err := zkConn.Children(GetProxyFencePath(productName)) if err != nil { if err.Error() == zk.ErrNoNode.Error() { return make(map[string]bool), nil } else { return nil, err } } m := make(map[string]bool, len(children)) for _, fenceNode := range children { m[fenceNode] = true } return m, nil }
func (self *ServerGroup) GetServers(zkConn zkhelper.Conn) ([]Server, error) { var ret []Server root := fmt.Sprintf("/zk/codis/db_%s/servers/group_%d", self.ProductName, self.Id) nodes, _, err := zkConn.Children(root) if err != nil { return nil, errors.Trace(err) } for _, node := range nodes { nodePath := root + "/" + node s, err := GetServer(zkConn, nodePath) if err != nil { return nil, errors.Trace(err) } ret = append(ret, *s) } return ret, nil }
func (sg *ServerGroup) GetServers(coordConn zkhelper.Conn) ([]*Server, error) { var ret []*Server root := fmt.Sprintf("/zk/reborn/db_%s/servers/group_%d", sg.ProductName, sg.Id) nodes, _, err := coordConn.Children(root) if err != nil { return nil, errors.Trace(err) } for _, node := range nodes { nodePath := root + "/" + node s, err := GetServer(coordConn, nodePath) if err != nil { return nil, errors.Trace(err) } ret = append(ret, s) } return ret, nil }
func ForceRemoveLock(zkConn zkhelper.Conn, productName string) error { lockPath := fmt.Sprintf("/zk/codis/db_%s/LOCK", productName) children, _, err := zkConn.Children(lockPath) if err != nil { return errors.Trace(err) } for _, c := range children { fullPath := path.Join(lockPath, c) log.Info("deleting..", fullPath) err := zkConn.Delete(fullPath, 0) if err != nil { return errors.Trace(err) } } return nil }
func ForceRemoveLock(coordConn zkhelper.Conn, productName string) error { lockPath := fmt.Sprintf("/zk/reborn/db_%s/LOCK", productName) children, _, err := coordConn.Children(lockPath) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return errors.Trace(err) } for _, c := range children { fullPath := path.Join(lockPath, c) log.Info("deleting..", fullPath) err := coordConn.Delete(fullPath, 0) if err != nil { return errors.Trace(err) } } return nil }
func ProxyList(zkConn zkhelper.Conn, productName string, filter func(*ProxyInfo) bool) ([]ProxyInfo, error) { ret := make([]ProxyInfo, 0) root := GetProxyPath(productName) proxies, _, err := zkConn.Children(root) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return nil, errors.Trace(err) } for _, proxyName := range proxies { pi, err := GetProxyInfo(zkConn, productName, proxyName) if err != nil { return nil, errors.Trace(err) } if filter == nil || filter(pi) == true { ret = append(ret, *pi) } } return ret, 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 }