code: func (w *worker) sendRangeTaskToWorkers(t table.Table, workers []*addIndexWorker, reorgInfo *reorgInfo, totalAddedCount *int64, kvRanges []kv.KeyRange) ([]kv.KeyRange, error) {
  	batchTasks := make([]*reorgIndexTask, 0, len(workers))
  	physicalTableID := reorgInfo.PhysicalTableID
  
  	// Build reorg indices tasks.
  	for _, keyRange := range kvRanges {
  		startHandle, endHandle, err := decodeHandleRange(keyRange)
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  
  		endKey := t.RecordKey(endHandle)
  		endIncluded := false
  		if endKey.Cmp(keyRange.EndKey) < 0 {
  			endIncluded = true
  		}
  		task := &reorgIndexTask{physicalTableID, startHandle, endHandle, endIncluded}
  		batchTasks = append(batchTasks, task)
  
  		if len(batchTasks) >= len(workers) {
  			break
  		}
  	}
  
  	if len(batchTasks) == 0 {
  		return nil, nil
  	}
  
  	// Wait tasks finish.
  	err := w.handleReorgTasks(reorgInfo, totalAddedCount, workers, batchTasks)
  	if err != nil {
  		return nil, errors.Trace(err)
  	}
  
  	if len(batchTasks) < len(kvRanges) {
  		// there are kvRanges not handled.
  		remains := kvRanges[len(batchTasks):]
  		return remains, nil
  	}
  
  	return nil, nil
  }
docs: // sendRangeTaskToWorkers sends tasks to workers, and returns remaining kvRanges that is not handled.