newScheduler uses scWeights to create a new scheduler for selecting endpoints in a picker. It will return a round robin implementation if at least len(scWeights)-1 are zero or there is only a single endpoint, otherwise it will return an Earliest Deadline First (EDF) scheduler implementation that se
(recordMetrics bool)
| 32 | // will return an Earliest Deadline First (EDF) scheduler implementation that |
| 33 | // selects the endpoints according to their weights. |
| 34 | func (p *picker) newScheduler(recordMetrics bool) scheduler { |
| 35 | epWeights := p.endpointWeights(recordMetrics) |
| 36 | n := len(epWeights) |
| 37 | if n == 0 { |
| 38 | return nil |
| 39 | } |
| 40 | if n == 1 { |
| 41 | if recordMetrics { |
| 42 | rrFallbackMetric.Record(p.metricsRecorder, 1, p.target, p.locality, p.clusterName) |
| 43 | } |
| 44 | return &rrScheduler{numSCs: 1, inc: p.inc} |
| 45 | } |
| 46 | sum := float64(0) |
| 47 | numZero := 0 |
| 48 | max := float64(0) |
| 49 | for _, w := range epWeights { |
| 50 | sum += w |
| 51 | if w > max { |
| 52 | max = w |
| 53 | } |
| 54 | if w == 0 { |
| 55 | numZero++ |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | if numZero >= n-1 { |
| 60 | if recordMetrics { |
| 61 | rrFallbackMetric.Record(p.metricsRecorder, 1, p.target, p.locality, p.clusterName) |
| 62 | } |
| 63 | return &rrScheduler{numSCs: uint32(n), inc: p.inc} |
| 64 | } |
| 65 | unscaledMean := sum / float64(n-numZero) |
| 66 | scalingFactor := maxWeight / max |
| 67 | mean := uint16(math.Round(scalingFactor * unscaledMean)) |
| 68 | |
| 69 | weights := make([]uint16, n) |
| 70 | allEqual := true |
| 71 | for i, w := range epWeights { |
| 72 | if w == 0 { |
| 73 | // Backends with weight = 0 use the mean. |
| 74 | weights[i] = mean |
| 75 | } else { |
| 76 | scaledWeight := uint16(math.Round(scalingFactor * w)) |
| 77 | weights[i] = scaledWeight |
| 78 | if scaledWeight != mean { |
| 79 | allEqual = false |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | if allEqual { |
| 85 | return &rrScheduler{numSCs: uint32(n), inc: p.inc} |
| 86 | } |
| 87 | |
| 88 | logger.Infof("using edf scheduler with weights: %v", weights) |
| 89 | return &edfScheduler{weights: weights, inc: p.inc} |
| 90 | } |
| 91 |
no test coverage detected