Пример #1
0
func (slv *slave) SendSlaveOfToMaster() error {
	slv.mtx.Lock()
	var mi = slv.mi
	var cli = slv.cli
	slv.mtx.Unlock()

	if cli == nil {
		return nil
	}

	var err error
	var pkg []byte
	if mi.Migration {
		var p ctrl.PkgMigrate
		p.ClientReq = false
		p.MasterAddr = mi.MasterAddr
		p.SlaveAddr = mi.SlaveAddr
		p.SlotId = mi.SlotId

		pkg, err = ctrl.Encode(proto.CmdMigrate, 0, 0, &p)
		if err != nil {
			return err
		}
	} else {
		lastSeq, valid := slv.bin.GetMasterSeq()
		if !valid {
			slv.mc.SetStatus(ctrl.SlaveNeedClear)
			// Any better solution?
			log.Fatalf("Slave lastSeq %d is out of sync, please clear old data! "+
				"(Restart may fix this issue)", lastSeq)
		}

		var p ctrl.PkgSlaveOf
		p.ClientReq = false
		p.MasterAddr = mi.MasterAddr
		p.SlaveAddr = mi.SlaveAddr
		p.LastSeq = lastSeq
		log.Printf("Connect to master %s with lastSeq %d\n",
			mi.MasterAddr, p.LastSeq)

		pkg, err = ctrl.Encode(proto.CmdSlaveOf, 0, 0, &p)
		if err != nil {
			return err
		}
	}

	cli.AddResp(pkg)
	return slv.mc.SetStatus(ctrl.SlaveFullSync)
}
Пример #2
0
func (srv *Server) slaveOf(req *Request) {
	var cliType uint32 = ClientTypeNormal
	if req.Cli != nil {
		cliType = req.Cli.ClientType()
	}

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

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

		if !req.Cli.IsAuth(proto.AdminDbId) {
			log.Printf("Not authorized!\n")
			srv.replySlaveOf(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.SetMaster(p.MasterAddr, p.SlaveAddr)
		if err != nil {
			log.Printf("Failed to set config: %s\n", err)
			srv.replySlaveOf(req, fmt.Sprintf("set 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()
			}
			srv.bin.AsSlave()
			srv.connectToMaster(srv.mc)
		} else {
			if slv != nil {
				go slv.DelayClose()
			}
			srv.bin.AsMaster()
		}

		srv.replySlaveOf(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 SlaveOf command, close now!",
				cliType)
		}
		req.Cli.Close()
	}
}