func apiMigrateStatus() (int, string) { migrateSlots, err := models.GetMigratingSlots(safeZkConn, globalEnv.ProductName()) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return 500, err.Error() } b, err := json.MarshalIndent(map[string]interface{}{ "migrate_slots": migrateSlots, "migrate_task": globalMigrateManager.runningTask, }, " ", " ") return 200, string(b) }
func apiSetProxyStatus(proxy models.ProxyInfo, param martini.Params) (int, string) { err := models.SetProxyStatus(safeZkConn, globalEnv.ProductName(), proxy.Id, proxy.State) if err != nil { // if this proxy is not online, just return success if proxy.State == models.PROXY_STATE_MARK_OFFLINE && zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return jsonRetSucc() } log.Warning(errors.ErrorStack(err)) return 500, err.Error() } return jsonRetSucc() }
func CreateOrUpdate(zconn zkhelper.Conn, zkPath, value string, flags int, aclv []topo.ACL, recursive bool) (pathCreated string, err error) { if recursive { pathCreated, err = CreateRecursive(zconn, zkPath, value, flags, aclv) } else { pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) } if err != nil && zkhelper.ZkErrorEqual(err, topo.ErrNodeExists) { pathCreated = "" _, err = zconn.Set(zkPath, []byte(value), -1) } return }
// Create a path and any pieces required, think mkdir -p. // Intermediate znodes are always created empty. func CreateRecursive(zconn zkhelper.Conn, zkPath, value string, flags int, aclv []topo.ACL) (pathCreated string, err error) { parts := strings.Split(zkPath, "/") if parts[1] != zkhelper.MagicPrefix { return "", fmt.Errorf("zkutil: non /%v path: %v", zkhelper.MagicPrefix, zkPath) } pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) if zkhelper.ZkErrorEqual(err, topo.ErrNoNode) { // Make sure that nodes are either "file" or "directory" to mirror file system // semantics. dirAclv := make([]topo.ACL, len(aclv)) for i, acl := range aclv { dirAclv[i] = acl dirAclv[i].Perms = zkhelper.PERM_DIRECTORY } _, err = CreateRecursive(zconn, os_path.Dir(zkPath), "", 0, dirAclv) if err != nil && !zkhelper.ZkErrorEqual(err, topo.ErrNodeExists) { return "", err } pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) } return }
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 && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { 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 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 apiOverview() (int, string) { // get all server groups groups, err := models.ServerGroups(unsafeZkConn, globalEnv.ProductName()) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return 500, err.Error() } var instances []string for _, group := range groups { for _, srv := range group.Servers { if srv.Type == "master" { instances = append(instances, srv.Addr) } } } info := make(map[string]interface{}) info["product"] = globalEnv.ProductName() info["ops"] = proxiesSpeed redisInfos := make([]map[string]string, 0) if len(instances) > 0 { for _, instance := range instances { info, err := utils.GetRedisStat(instance) if err != nil { log.Error(err) } redisInfos = append(redisInfos, info) } } info["redis_infos"] = redisInfos b, err := json.MarshalIndent(info, " ", " ") return 200, string(b) }
func SetProxyStatus(zkConn zkhelper.Conn, productName string, proxyName string, status string) error { p, err := GetProxyInfo(zkConn, productName, proxyName) if err != nil { return errors.Trace(err) } if status != PROXY_STATE_ONLINE && status != PROXY_STATE_MARK_OFFLINE && status != PROXY_STATE_OFFLINE { return errors.Errorf("%v, %s", ErrUnknownProxyStatus, status) } // check slot status before setting proxy online if status == PROXY_STATE_ONLINE { slots, err := Slots(zkConn, productName) if err != nil { return errors.Trace(err) } for _, slot := range slots { if slot.State.Status != SLOT_STATUS_ONLINE && slot.State.Status != SLOT_STATUS_MIGRATE { return errors.Errorf("slot %v is not online or migrate", slot) } if slot.GroupId == INVALID_ID { return errors.Errorf("slot %v has invalid group id", slot) } } } p.State = status b, _ := json.Marshal(p) _, err = zkConn.Set(path.Join(GetProxyPath(productName), proxyName), b, -1) if err != nil { return errors.Trace(err) } if status == PROXY_STATE_MARK_OFFLINE { // wait for the proxy down for { _, _, c, err := zkConn.GetW(path.Join(GetProxyPath(productName), proxyName)) if zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return nil } else if err != nil { return errors.Trace(err) } <-c info, err := GetProxyInfo(zkConn, productName, proxyName) log.Info("mark_offline, check proxy status:", proxyName, info, err) if zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { log.Info("shutdown proxy successful") return nil } else if err != nil { return errors.Trace(err) } if info.State == PROXY_STATE_OFFLINE { log.Infof("proxy: %s offline success!", proxyName) return nil } } } return nil }
func isConnectionError(e error) bool { return !zkhelper.ZkErrorEqual(zk.ErrNoNode, e) && !zkhelper.ZkErrorEqual(zk.ErrNodeExists, e) && !zkhelper.ZkErrorEqual(zk.ErrNodeExists, e) && !zkhelper.ZkErrorEqual(zk.ErrNotEmpty, e) }
func ActionGC(zkConn zkhelper.Conn, productName string, gcType int, keep int) error { prefix := GetWatchActionPath(productName) respPrefix := GetActionResponsePath(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) // keep last 500 actions if len(actions)-500 <= keep { return nil } for _, action := range actions[:len(actions)-keep-500] { if err := zkhelper.DeleteRecursive(zkConn, path.Join(prefix, action), -1); err != nil { return errors.Trace(err) } err := zkhelper.DeleteRecursive(zkConn, path.Join(respPrefix, action), -1) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { 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.Infof("action = %s, timestamp = %s", action, act.Ts) ts, _ := strconv.ParseInt(act.Ts, 10, 64) if currentTs-ts > int64(secs) { if err := zkhelper.DeleteRecursive(zkConn, path.Join(prefix, action), -1); err != nil { return errors.Trace(err) } err := zkhelper.DeleteRecursive(zkConn, path.Join(respPrefix, action), -1) if err != nil && !zkhelper.ZkErrorEqual(err, zk.ErrNoNode) { return errors.Trace(err) } } } actionResps, _, err := zkConn.Children(respPrefix) if err != nil { return errors.Trace(err) } for _, action := range actionResps { b, _, err := zkConn.Get(path.Join(respPrefix, action)) if err != nil { return errors.Trace(err) } if err := json.Unmarshal(b, &act); err != nil { return errors.Trace(err) } log.Infof("action = %s, timestamp = %s", action, act.Ts) ts, _ := strconv.ParseInt(act.Ts, 10, 64) if currentTs-ts > int64(secs) { if err := zkhelper.DeleteRecursive(zkConn, path.Join(respPrefix, action), -1); err != nil { return errors.Trace(err) } } } } return nil }
func (top *Topology) IsErrNodeExist(err error) bool { return zkhelper.ZkErrorEqual(err, topo.ErrNodeExists) }
func (top *Topology) IsErrClosing(err error) bool { return zkhelper.ZkErrorEqual(err, topo.ErrClosing) }
func (top *Topology) IsErrClose(err error) bool { return zkhelper.ZkErrorEqual(err, topo.ErrClosing) || zkhelper.ZkErrorEqual(err, topo.ErrConnectionClosed) || zkhelper.ZkErrorEqual(err, topo.ErrNoServer) }
func (top *Topology) IsErrSessionExpired(err error) bool { return zkhelper.ZkErrorEqual(err, topo.ErrSessionExpired) }
func (top *Topology) IsFatalErr(err error) bool { return zkhelper.ZkErrorEqual(err, topo.ErrSessionExpired) || zkhelper.ZkErrorEqual(err, topo.ErrNoNode) || top.IsErrClosing(err) }