github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/strategy/fill.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 "github.com/projecteru2/core/utils" 11 ) 12 13 // FillPlan deploy workload each node 14 // 根据之前部署的策略每一台补充到 N 个,已经超过 N 个的节点视为已满足 15 // need 是每台上限, limit 是限制节点数, 保证最终状态至少有 limit*need 个实例 16 // limit = 0 代表对所有节点进行填充 17 func FillPlan(ctx context.Context, infos []Info, need, _, limit int) (_ map[string]int, err error) { 18 log.WithFunc("strategy.FillPlan").Debugf(ctx, "need %d limit %d infos %+v", need, limit, infos) 19 scheduleInfosLength := len(infos) 20 if limit == 0 { 21 limit = scheduleInfosLength 22 } 23 if scheduleInfosLength < limit { 24 return nil, errors.Wrapf(types.ErrInsufficientResource, "node len %d cannot alloc a fill node plan", scheduleInfosLength) 25 } 26 sort.Slice(infos, func(i, j int) bool { 27 if infos[i].Count == infos[j].Count { 28 return infos[i].Capacity > infos[j].Capacity 29 } 30 return infos[i].Count > infos[j].Count 31 }) 32 deployMap, toDeploy := make(map[string]int), 0 33 for _, info := range infos { 34 if info.Count+info.Capacity >= need { 35 deployMap[info.Nodename] += utils.Max(need-info.Count, 0) 36 toDeploy += deployMap[info.Nodename] 37 limit-- 38 if limit == 0 { 39 if toDeploy == 0 { 40 err = types.ErrAlreadyFilled 41 } 42 return deployMap, err 43 } 44 } 45 } 46 return nil, errors.Wrapf(types.ErrInsufficientResource, "not enough nodes that can fill up to %d instances, require %d nodes", need, limit) 47 }