func (rowCache *InvalidationProcessor) runInvalidationLoop() {
	if !IsCachePoolAvailable() {
		log.Infof("Rowcache is not enabled. Not running invalidator.")
		return
	}
	if !rowCache.state.CompareAndSwap(RCINV_DISABLED, RCINV_ENABLED) {
		log.Infof("Rowcache invalidator already running")
		return
	}

	defer func() {
		rowCache.state.Set(RCINV_DISABLED)
		DisallowQueries()
	}()

	groupId, err := mysqlctl.GetReplicationPosition()
	if err != nil {
		log.Errorf("Rowcache invalidator could not start: cannot determine replication position: %v", err)
		return
	}

	log.Infof("Starting rowcache invalidator")
	req := &myproto.UpdateStreamRequest{GroupId: groupId}
	err = mysqlctl.ServeUpdateStream(req, func(reply interface{}) error {
		return rowCache.processEvent(reply.(*myproto.StreamEvent))
	})
	if err != nil {
		log.Errorf("mysqlctl.ServeUpdateStream returned err '%v'", err.Error())
	}
	log.Infof("Rowcache invalidator stopped")
}
func (rowCache *InvalidationProcessor) runInvalidationLoop() {
	var err error
	purgeCache := false
	purgeReason := ""

	replPos, err := mysqlctl.GetReplicationPosition()
	if err != nil {
		rErr := NewInvalidationError(FATAL_ERROR, fmt.Sprintf("Cannot determine replication position %v", err), "")
		rowCache.updateErrCounters(rErr)
		rowCache.stopCache(rErr.Error())
		return
	}

	startPosition := &mysqlctl.BinlogPosition{Position: *replPos}
	checkpoint, ok := rowCache.getCheckpoint()

	// Cannot resume from last checkpoint position.
	// Purging the cache.
	if !ok {
		purgeCache = true
		purgeReason = "Error in locating invalidation checkpoint"
	} else if checkpoint == nil {
		//NOTE: not purging the cache here - since no checkpoint is found, assuming cache is empty.
		relog.Info("No saved position found, invalidation starting at current replication position.")
	} else if !isCheckpointValid(&checkpoint.Position, replPos) {
		purgeCache = true
		purgeReason = "Invalidation checkpoint too old"
	} else {
		relog.Info("Starting at saved checkpoint %v", checkpoint.String())
		startPosition = checkpoint
	}

	if purgeCache {
		PurgeRowCache()
		startPosition = &mysqlctl.BinlogPosition{Position: *replPos}
		relog.Warning("Purging cache because '%v'", purgeReason)
	}

	relog.Info("Starting @ %v", startPosition.String())
	req := &mysqlctl.UpdateStreamRequest{StartPosition: *startPosition}
	err = mysqlctl.ServeUpdateStream(req, rowCache.receiveEvent)
	if err != nil {
		relog.Error("mysqlctl.ServeUpdateStream returned err '%v'", err.Error())
		if rErr, ok := err.(*InvalidationError); ok {
			rowCache.updateErrCounters(rErr)
		}
		rowCache.stopCache(fmt.Sprintf("Unexpected or fatal error, '%v'", err.Error()))
	}
}
func (rowCache *InvalidationProcessor) runInvalidationLoop() {
	var err error

	replPos, err := mysqlctl.GetReplicationPosition()
	if err != nil {
		rErr := NewInvalidationError(FATAL_ERROR, fmt.Sprintf("Cannot determine replication position %v", err), "")
		rowCache.updateErrCounters(rErr)
		rowCache.stopCache(rErr.Error())
		return
	}

	startPosition := &cproto.BinlogPosition{Position: *replPos}

	relog.Info("Starting @ %v", startPosition.String())
	req := &mysqlctl.UpdateStreamRequest{StartPosition: *startPosition}
	err = mysqlctl.ServeUpdateStream(req, rowCache.receiveEvent)
	if err != nil {
		relog.Error("mysqlctl.ServeUpdateStream returned err '%v'", err.Error())
		if rErr, ok := err.(*InvalidationError); ok {
			rowCache.updateErrCounters(rErr)
		}
		rowCache.stopCache(fmt.Sprintf("Unexpected or fatal error, '%v'", err.Error()))
	}
}