예제 #1
0
파일: server.go 프로젝트: tradia/gotable
func (srv *Server) deleteSlot(req *Request) {
	var cliType uint32 = ClientTypeNormal
	if req.Cli != nil {
		cliType = req.Cli.ClientType()
	}

	switch cliType {
	case ClientTypeNormal:
		var p ctrl.PkgDelSlot
		var err = ctrl.Decode(req.Pkg, nil, &p)
		p.ErrMsg = ""
		if err != nil {
			p.ErrMsg = fmt.Sprintf("decode failed %s", err)
		} else {
			err = srv.deleteMigrationSlot(p.SlotId, srv.mc.GetMaster())
			if err != nil {
				p.ErrMsg = fmt.Sprintf("delete slot failed %s", err)
			}
		}

		pkg, err := ctrl.Encode(req.Cmd, req.DbId, req.Seq, &p)
		if err == nil {
			srv.sendResp(false, req, pkg)
		}
	case ClientTypeSlave:
		fallthrough
	case ClientTypeMaster:
		log.Println("Invalid client type %d for DelSlot command, close now!",
			cliType)
		req.Cli.Close()
	}
}
예제 #2
0
파일: context.go 프로젝트: tradia/gotable
func (call *Call) replyInnerCtrl(p interface{}) (interface{}, error) {
	err := ctrl.Decode(call.pkg, nil, p)
	if err != nil {
		call.err = err
		return nil, call.err
	}
	return p, nil
}
예제 #3
0
파일: server.go 프로젝트: tradia/gotable
func (srv *Server) slaveStatus(req *Request) {
	var cliType uint32 = ClientTypeNormal
	if req.Cli != nil {
		cliType = req.Cli.ClientType()
	}

	switch cliType {
	case ClientTypeNormal:
		var p ctrl.PkgSlaveStatus
		var err = ctrl.Decode(req.Pkg, nil, &p)
		p.ErrMsg = ""
		if err != nil {
			p.ErrMsg = fmt.Sprintf("decode failed %s", err)
		} else {
			m := srv.mc.GetMaster()
			if len(m.MasterAddr) > 0 {
				if p.Migration {
					if !m.Migration {
						p.ErrMsg = fmt.Sprintf("check migration status on normal slave")
					} else if m.SlotId != p.SlotId {
						p.ErrMsg = fmt.Sprintf("slot id mismatch (%d, %d)",
							m.SlotId, p.SlotId)
					}
				} else {
					if m.Migration {
						p.ErrMsg = fmt.Sprintf("check normal slave status on migration")
					}
				}
			}
			if len(p.ErrMsg) == 0 {
				p.Status = m.Status
			}
		}

		pkg, err := ctrl.Encode(req.Cmd, req.DbId, req.Seq, &p)
		if err == nil {
			srv.sendResp(false, req, pkg)
		}
	case ClientTypeSlave:
		fallthrough
	case ClientTypeMaster:
		log.Println("Invalid client type %d for MigStatus command, close now!",
			cliType)
		req.Cli.Close()
	}
}
예제 #4
0
파일: server.go 프로젝트: tradia/gotable
func (srv *Server) migrate(req *Request) {
	var cliType uint32 = ClientTypeNormal
	if req.Cli != nil {
		cliType = req.Cli.ClientType()
	}

	var p ctrl.PkgMigrate
	var err = ctrl.Decode(req.Pkg, nil, &p)
	if err == nil && !p.ClientReq {
		srv.newMigMaster(req, &p)
		return
	}

	switch cliType {
	case ClientTypeNormal:
		if err != nil {
			log.Printf("Failed to Decode pkg: %s\n", err)
			srv.replyMigrate(req, fmt.Sprintf("decode failed(%s)", err))
			return
		}

		if !req.Cli.IsAuth(proto.AdminDbId) {
			log.Printf("Not authorized!\n")
			srv.replyMigrate(req, "no priviledge")
			return
		}

		if len(p.SlaveAddr) == 0 {
			p.SlaveAddr = req.Cli.LocalAddr().String()
		}
		if sameAddress(p.MasterAddr, p.SlaveAddr, req) {
			log.Printf("Master and slave addresses are the same!\n")
			srv.replyMigrate(req, "master and slave addresses are the same")
			return
		}

		err = srv.mc.SetMigration(p.MasterAddr, p.SlaveAddr, p.SlotId)
		if err != nil {
			log.Printf("Failed to update migration config: %s\n", err)
			srv.replyMigrate(req,
				fmt.Sprintf("update migration config failed(%s)", err))
			return
		}

		srv.rwMtx.Lock()
		slv := srv.slv
		srv.slv = nil
		srv.rwMtx.Unlock()

		if len(p.MasterAddr) > 0 {
			if slv != nil {
				slv.Close()
			}
			if srv.tbl.HasSlotData(p.SlotId) {
				err = srv.mc.SetStatus(ctrl.SlaveNeedClear)
				if err != nil {
					log.Printf("Failed to set migration status: %s\n", err)
					srv.replyMigrate(req,
						fmt.Sprintf("failed to set migration status(%s)", err))
					return
				}
			} else {
				srv.connectToMaster(srv.mc)
			}
		} else {
			if slv != nil {
				go slv.DelayClose()
			}
			srv.bin.AsMaster()
		}

		srv.replyMigrate(req, "") // Success
	case ClientTypeSlave:
		fallthrough
	case ClientTypeMaster:
		if err != nil {
			log.Printf("Failed to Decode pkg: %s\n", err)
		} else {
			log.Println("Invalid client type %d for Migrate command, close now!",
				cliType)
		}
		req.Cli.Close()
	}
}