示例#1
0
// ApplyBinlogEvents makes a bson rpc request to BinlogServer
// and processes the events.
func (blp *BinlogPlayer) ApplyBinlogEvents(interrupted chan struct{}) error {
	log.Infof("BinlogPlayer client for keyrange '%v:%v' starting @ '%v'",
		blp.recoveryState.KeyrangeStart,
		blp.recoveryState.KeyrangeEnd,
		blp.recoveryState.Position)

	var err error
	log.Infof("Dialing server @ %v", blp.recoveryState.Addr)
	blp.rpcClient, err = rpcplus.DialHTTP("tcp", blp.recoveryState.Addr)
	defer blp.rpcClient.Close()
	if err != nil {
		log.Errorf("Error in dialing to vt_binlog_server, %v", err)
		return fmt.Errorf("Error in dialing to vt_binlog_server, %v", err)
	}

	responseChan := make(chan *cproto.BinlogResponse)
	log.Infof("making rpc request @ %v for keyrange %v:%v", blp.recoveryState.Position, blp.recoveryState.KeyrangeStart, blp.recoveryState.KeyrangeEnd)
	blServeRequest := &cproto.BinlogServerRequest{
		StartPosition: blp.recoveryState.Position,
		KeyspaceStart: blp.recoveryState.KeyrangeStart,
		KeyspaceEnd:   blp.recoveryState.KeyrangeEnd}
	resp := blp.rpcClient.StreamGo("BinlogServer.ServeBinlog", blServeRequest, responseChan)

processLoop:
	for {
		select {
		case response, ok := <-responseChan:
			if !ok {
				break processLoop
			}
			err = blp.processBinlogEvent(response)
			if err != nil {
				return fmt.Errorf("Error in processing binlog event %v", err)
			}
		case <-interrupted:
			return nil
		}
	}
	if resp.Error != nil {
		return fmt.Errorf("Error received from ServeBinlog %v", resp.Error)
	}
	return nil
}
示例#2
0
//This makes a bson rpc request to the vt_binlog_server
//and processes the events.
func (blp *BinlogPlayer) applyBinlogEvents() error {
	var err error
	connectionStr := fmt.Sprintf("%v:%v", blp.startPosition.Host, SERVER_PORT)
	relog.Info("Dialing server @ %v", connectionStr)
	blp.rpcClient, err = rpcplus.DialHTTP("tcp", connectionStr)
	defer blp.rpcClient.Close()
	if err != nil {
		relog.Error("Error in dialing to vt_binlog_server, %v", err)
		return fmt.Errorf("Error in dialing to vt_binlog_server, %v", err)
	}

	responseChan := make(chan *mysqlctl.BinlogResponse)
	relog.Info("making rpc request @ %v for keyrange %v:%v", blp.startPosition.Position, blp.startPosition.KeyrangeStart, blp.startPosition.KeyrangeEnd)
	blServeRequest := &mysqlctl.BinlogServerRequest{StartPosition: blp.startPosition.Position,
		KeyspaceStart: blp.startPosition.KeyrangeStart,
		KeyspaceEnd:   blp.startPosition.KeyrangeEnd}
	resp := blp.rpcClient.StreamGo("BinlogServer.ServeBinlog", blServeRequest, responseChan)

processLoop:
	for {
		select {
		case response, ok := <-responseChan:
			if !ok {
				break processLoop
			}
			err = blp.processBinlogEvent(response)
			if err != nil {
				return fmt.Errorf("Error in processing binlog event %v", err)
			}
		case <-interrupted:
			return nil
		}
	}
	if resp.Error != nil {
		return fmt.Errorf("Error received from ServeBinlog %v", resp.Error)
	}
	return nil
}
示例#3
0
// ApplyBinlogEvents makes a gob rpc request to BinlogServer
// and processes the events. It will return nil if 'interrupted'
// was closed, or if we reached the stopping point.
// It will return io.EOF if the server stops sending us updates.
// It may return any other error it encounters.
func (blp *BinlogPlayer) ApplyBinlogEvents(interrupted chan struct{}) error {
	if len(blp.tables) > 0 {
		log.Infof("BinlogPlayer client %v for tables %v starting @ '%v', server: %v",
			blp.blpPos.Uid,
			blp.tables,
			blp.blpPos.GroupId,
			blp.addr,
		)
	} else {
		log.Infof("BinlogPlayer client %v for keyrange '%v-%v' starting @ '%v', server: %v",
			blp.blpPos.Uid,
			blp.keyRange.Start.Hex(),
			blp.keyRange.End.Hex(),
			blp.blpPos.GroupId,
			blp.addr,
		)
	}
	if blp.stopAtGroupId > 0 {
		// we need to stop at some point
		// sanity check the point
		if blp.blpPos.GroupId > blp.stopAtGroupId {
			return fmt.Errorf("starting point %v greater than stopping point %v", blp.blpPos.GroupId, blp.stopAtGroupId)
		} else if blp.blpPos.GroupId == blp.stopAtGroupId {
			log.Infof("Not starting BinlogPlayer, we're already at the desired position %v", blp.stopAtGroupId)
			return nil
		}
		log.Infof("Will stop player when reaching %v", blp.stopAtGroupId)
	}
	rpcClient, err := rpcplus.DialHTTP("tcp", blp.addr)
	defer rpcClient.Close()
	if err != nil {
		log.Errorf("Error dialing binlog server: %v", err)
		return fmt.Errorf("error dialing binlog server: %v", err)
	}

	responseChan := make(chan *proto.BinlogTransaction)
	var resp *rpcplus.Call
	if len(blp.tables) > 0 {
		req := &proto.TablesRequest{
			Tables:  blp.tables,
			GroupId: blp.blpPos.GroupId,
		}
		resp = rpcClient.StreamGo("UpdateStream.StreamTables", req, responseChan)
	} else {
		req := &proto.KeyRangeRequest{
			KeyRange: blp.keyRange,
			GroupId:  blp.blpPos.GroupId,
		}
		resp = rpcClient.StreamGo("UpdateStream.StreamKeyRange", req, responseChan)
	}

processLoop:
	for {
		select {
		case response, ok := <-responseChan:
			if !ok {
				break processLoop
			}
			for {
				ok, err = blp.processTransaction(response)
				if err != nil {
					return fmt.Errorf("Error in processing binlog event %v", err)
				}
				if ok {
					if blp.stopAtGroupId > 0 && blp.blpPos.GroupId >= blp.stopAtGroupId {
						log.Infof("Reached stopping position, done playing logs")
						return nil
					}
					break
				}
				log.Infof("Retrying txn")
				time.Sleep(1 * time.Second)
			}
		case <-interrupted:
			return nil
		}
	}
	if resp.Error != nil {
		return fmt.Errorf("Error received from ServeBinlog %v", resp.Error)
	}
	return io.EOF
}
示例#4
0
func (client *GoRpcBinlogPlayerClient) Dial(addr string) error {
	var err error
	client.Client, err = rpcplus.DialHTTP("tcp", addr)
	return err
}