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  }