vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletserver/throttle/mysql.go (about) 1 /* 2 Copyright 2017 GitHub Inc. 3 4 Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE 5 */ 6 7 package throttle 8 9 import ( 10 "context" 11 "sort" 12 13 "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" 14 "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" 15 ) 16 17 func aggregateMySQLProbes( 18 ctx context.Context, 19 probes *mysql.Probes, 20 clusterName string, 21 instanceResultsMap mysql.InstanceMetricResultMap, 22 ignoreHostsCount int, 23 IgnoreDialTCPErrors bool, 24 ignoreHostsThreshold float64, 25 ) (worstMetric base.MetricResult) { 26 // probes is known not to change. It can be *replaced*, but not changed. 27 // so it's safe to iterate it 28 probeValues := []float64{} 29 for _, probe := range *probes { 30 instanceMetricResult, ok := instanceResultsMap[mysql.GetClusterInstanceKey(clusterName, &probe.Key)] 31 if !ok { 32 return base.NoMetricResultYet 33 } 34 35 value, err := instanceMetricResult.Get() 36 if err != nil { 37 if IgnoreDialTCPErrors && base.IsDialTCPError(err) { 38 continue 39 } 40 if ignoreHostsCount > 0 { 41 // ok to skip this error 42 ignoreHostsCount = ignoreHostsCount - 1 43 continue 44 } 45 return instanceMetricResult 46 } 47 48 // No error 49 probeValues = append(probeValues, value) 50 } 51 if len(probeValues) == 0 { 52 return base.NoHostsMetricResult 53 } 54 55 // If we got here, that means no errors (or good-to-skip errors) 56 sort.Float64s(probeValues) 57 // probeValues sorted ascending (from best, ie smallest, to worst, ie largest) 58 for ignoreHostsCount > 0 { 59 goodToIgnore := func() bool { 60 // Note that these hosts don't have errors 61 numProbeValues := len(probeValues) 62 if numProbeValues <= 1 { 63 // We wish to retain at least one host 64 return false 65 } 66 if ignoreHostsThreshold <= 0 { 67 // No threshold conditional (or implicitly "any value exceeds the threshold") 68 return true 69 } 70 if worstValue := probeValues[numProbeValues-1]; worstValue > ignoreHostsThreshold { 71 return true 72 } 73 return false 74 }() 75 if goodToIgnore { 76 probeValues = probeValues[0 : len(probeValues)-1] 77 } 78 // And, whether ignored or not, we are reducing our tokens 79 ignoreHostsCount = ignoreHostsCount - 1 80 } 81 worstValue := probeValues[len(probeValues)-1] 82 worstMetric = base.NewSimpleMetricResult(worstValue) 83 return worstMetric 84 }