github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/strategy/average.go (about)

     1  package strategy
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  
     7  	"github.com/cockroachdb/errors"
     8  	"github.com/projecteru2/core/log"
     9  	"github.com/projecteru2/core/types"
    10  )
    11  
    12  // AveragePlan deploy workload each node
    13  // 容量够的机器每一台部署 N 个
    14  // need 是每台机器所需总量,limit 是限制节点数, 保证本轮增量部署 need*limit 个实例
    15  // limit = 0 即对所有节点部署
    16  func AveragePlan(ctx context.Context, infos []Info, need, _, limit int) (map[string]int, error) {
    17  	log.WithFunc("strategy.AveragePlan").Debugf(ctx, "need %d limit %d infos %+v", need, limit, infos)
    18  	scheduleInfosLength := len(infos)
    19  	if limit == 0 {
    20  		limit = scheduleInfosLength
    21  	}
    22  	if scheduleInfosLength < limit {
    23  		return nil, errors.Wrapf(types.ErrInsufficientResource, "node len %d < limit, cannot alloc an average node plan", scheduleInfosLength)
    24  	}
    25  	sort.Slice(infos, func(i, j int) bool { return infos[i].Capacity > infos[j].Capacity })
    26  	p := sort.Search(scheduleInfosLength, func(i int) bool { return infos[i].Capacity < need })
    27  	if p == 0 {
    28  		return nil, errors.Wrap(types.ErrInsufficientCapacity, "insufficient nodes, at least 1 needed")
    29  	}
    30  	if p < limit {
    31  		return nil, errors.Wrapf(types.ErrInsufficientResource, "not enough nodes with capacity of %d, require %d nodes", need, limit)
    32  	}
    33  	deployMap := map[string]int{}
    34  	for _, strategyInfo := range infos[:limit] {
    35  		deployMap[strategyInfo.Nodename] += need
    36  	}
    37  
    38  	return deployMap, nil
    39  }