MCPcopy
hub / github.com/fabiolb/fabio / weighTargets

Method weighTargets

route/route.go:213–317  ·  view source on GitHub ↗

10000 weighTargets computes the share of traffic each target receives based on its weight and the weight of the other targets. Traffic is first distributed to targets with a fixed weight. If the sum of all fixed weights exceeds 100% then they are normalized to 100%. Targets with a dynamic weight w

()

Source from the content-addressed store, hash-verified

211// Targets with a dynamic weight will receive an equal share of the remaining
212// traffic if there is any left.
213func (r *Route) weighTargets() {
214 // how big is the fixed weighted traffic?
215 var nFixed int
216 var sumFixed float64
217 for _, t := range r.Targets {
218 if t.FixedWeight > 0 {
219 nFixed++
220 sumFixed += t.FixedWeight
221 }
222 }
223
224 // if there are no targets with fixed weight then each target simply gets
225 // an equal amount of traffic
226 if nFixed == 0 {
227 w := 1.0 / float64(len(r.Targets))
228 for _, t := range r.Targets {
229 t.Weight = w
230 }
231 r.wTargets = r.Targets
232 return
233 }
234
235 // normalize fixed weights up (sumFixed < 1) or down (sumFixed > 1)
236 scale := 1.0
237 if sumFixed > 1 || (nFixed == len(r.Targets) && sumFixed < 1) {
238 scale = 1 / sumFixed
239 }
240
241 // compute the weight for the targets with dynamic weights
242 dynamic := (1 - sumFixed) / float64(len(r.Targets)-nFixed)
243 if dynamic < 0 {
244 dynamic = 0
245 }
246
247 // assign the actual weight to each target
248 for _, t := range r.Targets {
249 if t.FixedWeight > 0 {
250 t.Weight = t.FixedWeight * scale
251 } else {
252 t.Weight = dynamic
253 }
254 }
255
256 // distribute the targets on a ring suitable for weighted round-robin
257 // distribution
258 //
259 // This is done in two steps:
260 //
261 // Step one determines the necessary ring size to distribute the targets
262 // according to their weight with reasonable accuracy. For example, two
263 // targets with 50% weight fit in a ring of size 2 whereas two targets with
264 // 10% and 90% weight require a ring of size 10.
265 //
266 // To keep it simple we allocate 10000 slots which provides slots to all
267 // targets with at least a weight of 0.01%. In addition, we guarantee that
268 // every target with a weight > 0 gets at least one slot. The case where
269 // all targets get an equal share of traffic is handled earlier so this is
270 // for situations with some fixed weight.

Callers 3

addTargetMethod · 0.95
filterMethod · 0.95
setWeightMethod · 0.95

Calls

no outgoing calls

Tested by

no test coverage detected