func (s *Slot) Update(zkConn zkhelper.Conn) error { // status validation switch s.State.Status { case SLOT_STATUS_MIGRATE, SLOT_STATUS_OFFLINE, SLOT_STATUS_ONLINE, SLOT_STATUS_PRE_MIGRATE: { // valid status, OK } default: { return errors.Trace(ErrUnknownSlotStatus) } } data, err := json.Marshal(s) if err != nil { return errors.Trace(err) } zkPath := GetSlotPath(s.ProductName, s.Id) _, err = zkhelper.CreateOrUpdate(zkConn, zkPath, string(data), 0, zkhelper.DefaultFileACLs(), true) if err != nil { return errors.Trace(err) } if s.State.Status == SLOT_STATUS_MIGRATE { err = NewAction(zkConn, s.ProductName, ACTION_TYPE_SLOT_MIGRATE, s, "", true) } else { err = NewAction(zkConn, s.ProductName, ACTION_TYPE_SLOT_CHANGED, s, "", true) } return errors.Trace(err) }
func (self *ServerGroup) AddServer(zkConn zkhelper.Conn, s *Server, passwd string) error { s.GroupId = self.Id servers, err := self.GetServers(zkConn) if err != nil { return errors.Trace(err) } var masterAddr string for _, server := range servers { if server.Type == SERVER_TYPE_MASTER { masterAddr = server.Addr } } // make sure there is only one master if s.Type == SERVER_TYPE_MASTER && len(masterAddr) > 0 { return errors.Trace(ErrNodeExists) } // if this group has no server. auto promote this server to master if len(servers) == 0 { s.Type = SERVER_TYPE_MASTER } val, err := json.Marshal(s) if err != nil { return errors.Trace(err) } zkPath := fmt.Sprintf("/zk/codis/db_%s/servers/group_%d/%s", self.ProductName, self.Id, s.Addr) _, err = zkhelper.CreateOrUpdate(zkConn, zkPath, string(val), 0, zkhelper.DefaultFileACLs(), true) if err != nil { return errors.Trace(err) } // update servers servers, err = self.GetServers(zkConn) if err != nil { return errors.Trace(err) } self.Servers = servers if s.Type == SERVER_TYPE_MASTER { err = NewAction(zkConn, self.ProductName, ACTION_TYPE_SERVER_GROUP_CHANGED, self, "", true) if err != nil { return errors.Trace(err) } } else if s.Type == SERVER_TYPE_SLAVE && len(masterAddr) > 0 { // send command slaveof to slave err := utils.SlaveOf(s.Addr, passwd, masterAddr) if err != nil { return errors.Trace(err) } } return nil }
func CreateActionRootPath(zkConn zkhelper.Conn, path string) error { // if action dir not exists, create it first exists, err := zkhelper.NodeExists(zkConn, path) if err != nil { return errors.Trace(err) } if !exists { _, err := zkhelper.CreateOrUpdate(zkConn, path, "", 0, zkhelper.DefaultDirACLs(), true) if err != nil { return errors.Trace(err) } } return nil }
func (self *ServerGroup) Create(zkConn zkhelper.Conn) error { if self.Id < 0 { return errors.Errorf("invalid server group id %d", self.Id) } zkPath := fmt.Sprintf("/zk/codis/db_%s/servers/group_%d", self.ProductName, self.Id) _, err := zkhelper.CreateOrUpdate(zkConn, zkPath, "", 0, zkhelper.DefaultDirACLs(), true) if err != nil { return errors.Trace(err) } err = NewAction(zkConn, self.ProductName, ACTION_TYPE_SERVER_GROUP_CHANGED, self, "", false) if err != nil { return errors.Trace(err) } return nil }
func SetSlotRange(zkConn zkhelper.Conn, productName string, fromSlot, toSlot, groupId int, status SlotStatus) error { if status != SLOT_STATUS_OFFLINE && status != SLOT_STATUS_ONLINE { return errors.Errorf("invalid status") } ok, err := GroupExists(zkConn, productName, groupId) if err != nil { return errors.Trace(err) } if !ok { return errors.Errorf("group %d is not found", groupId) } for i := fromSlot; i <= toSlot; i++ { s, err := GetSlot(zkConn, productName, i) if err != nil { return errors.Trace(err) } if s.State.Status != SLOT_STATUS_OFFLINE { return errors.New(fmt.Sprintf("slot %d is not offline, if you want to change the group for a slot, use migrate", s.Id)) } s.GroupId = groupId s.State.Status = status data, err := json.Marshal(s) if err != nil { return errors.Trace(err) } zkPath := GetSlotPath(productName, i) _, err = zkhelper.CreateOrUpdate(zkConn, zkPath, string(data), 0, zkhelper.DefaultFileACLs(), true) if err != nil { return errors.Trace(err) } } param := SlotMultiSetParam{ From: fromSlot, To: toSlot, GroupId: groupId, Status: status, } err = NewAction(zkConn, productName, ACTION_TYPE_MULTI_SLOT_CHANGED, param, "", true) return errors.Trace(err) }
func SetSlots(zkConn zkhelper.Conn, productName string, slots []*Slot, groupId int, status SlotStatus) error { if status != SLOT_STATUS_OFFLINE && status != SLOT_STATUS_ONLINE { return errors.Errorf("invalid status") } ok, err := GroupExists(zkConn, productName, groupId) if err != nil { return errors.Trace(err) } if !ok { return errors.Errorf("group %d is not found", groupId) } for _, s := range slots { s.GroupId = groupId s.State.Status = status data, err := json.Marshal(s) if err != nil { return errors.Trace(err) } zkPath := GetSlotPath(productName, s.Id) _, err = zkhelper.CreateOrUpdate(zkConn, zkPath, string(data), 0, zkhelper.DefaultFileACLs(), true) if err != nil { return errors.Trace(err) } } param := SlotMultiSetParam{ From: -1, To: -1, GroupId: groupId, Status: status, } err = NewAction(zkConn, productName, ACTION_TYPE_MULTI_SLOT_CHANGED, param, "", true) return errors.Trace(err) }
func (self *ServerGroup) Create(zkConn zkhelper.Conn) error { if self.Id < 0 { return errors.Errorf("invalid server group id %d", self.Id) } zkPath := fmt.Sprintf("/zk/codis/db_%s/servers/group_%d", self.ProductName, self.Id) _, err := zkhelper.CreateOrUpdate(zkConn, zkPath, "", 0, zkhelper.DefaultDirACLs(), true) if err != nil { return errors.Trace(err) } err = NewAction(zkConn, self.ProductName, ACTION_TYPE_SERVER_GROUP_CHANGED, self, "", false) if err != nil { return errors.Trace(err) } // set no server slots' group id to this server group, no need to return error slots, err := NoGroupSlots(zkConn, self.ProductName) if err == nil && len(slots) > 0 { SetSlots(zkConn, self.ProductName, slots, self.Id, SLOT_STATUS_ONLINE) } return nil }