// ScatterRegions relocates the regions. If the group is defined, the regions' leader with the same group would be scattered
// in a group level instead of cluster level.
// RetryTimes indicates the retry times if any of the regions failed to relocate during scattering. There will be
// time.Sleep between each retry.
// Failures indicates the regions which are failed to be relocated, the key of the failures indicates the regionID
// and the value of the failures indicates the failure error.
ScatterRegions relocates the regions. If the group is defined, the regions' leader with the same group would be scattered
in a group level instead of cluster level.
RetryTimes indicates the retry times if any of the regions failed to relocate during scattering. There will be
time.Sleep between each retry.
Failures indicates the regions which are failed to be relocated, the key of the failures indicates the regionID
and the value of the failures indicates the failure error.
// ScatterRegions relocates the regions . If the group is defined the regions ' leader with the same group would be scattered // in a group level instead of cluster level . // RetryTimes indicates the retry times if any of the regions failed to relocate during scattering . There will be // time . Sleep between each retry . // Failures indicates the regions which are failed to be relocated the key of the failures indicates the regionID // and the value of the failures indicates the failure error .
func (r *RegionScatterer) ScatterRegions(regions map[uint64]*core.RegionInfo, failures map[uint64]error, group string, retryLimit int) ([]*operator.Operator, error) {
	if len(regions) < 1 {
		scatterCounter.WithLabelValues("skip", "empty-region").Inc()
		return nil, errors.New("empty region")
	}
	if retryLimit > maxRetryLimit {
		retryLimit = maxRetryLimit
	}
	ops := make([]*operator.Operator, 0, len(regions))
	for currentRetry := 0; currentRetry <= retryLimit; currentRetry++ {
		for _, region := range regions {
			op, err := r.Scatter(region, group)
			failpoint.Inject("scatterFail", func() {
				if region.GetID() == 1 {
					err = errors.New("mock error")
				}
			})
			if err != nil {
				failures[region.GetID()] = err
				continue
			}
			if op != nil {
				ops = append(ops, op)
			}
			delete(regions, region.GetID())
			delete(failures, region.GetID())
		}
		if len(regions) < 1 {
			break
		}
		time.Sleep(typeutil.MinDuration(maxSleepDuration, time.Duration(math.Pow(2, float64(currentRetry)))*initialSleepDuration))
	}
	return ops, nil
}
func ( r * RegionScatterer ) ScatterRegions ( regions map [ uint64 ] * core . RegionInfo , failures map [ uint64 ] error , group string , retryLimit int ) ( [ ] * operator . Operator , error ) { if len ( regions ) < 1 { scatterCounter . WithLabelValues ( " " , " " ) . Inc ( ) return nil , errors . New ( " " ) } if retryLimit > maxRetryLimit { retryLimit = maxRetryLimit } ops := make ( [ ] * operator . Operator , 0 , len ( regions ) ) for currentRetry := 0 ; currentRetry <= retryLimit ; currentRetry ++ { for _ , region := range regions { op , err := r . Scatter ( region , group ) failpoint . Inject ( " " , func ( ) { if region . GetID ( ) == 1 { err = errors . New ( " " ) } } ) if err != nil { failures [ region . GetID ( ) ] = err continue } if op != nil { ops = append ( ops , op ) } delete ( regions , region . GetID ( ) ) delete ( failures , region . GetID ( ) ) } if len ( regions ) < 1 { break } time . Sleep ( typeutil . MinDuration ( maxSleepDuration , time . Duration ( math . Pow ( 2 , float64 ( currentRetry ) ) ) * initialSleepDuration ) ) } return ops , nil }
ScatterRegions relocates the regions.
ScatterRegions relocates the regions .
// all regions have been relocated, break the loop. // Wait for a while if there are some regions failed to be relocated