vitess.io/vitess@v0.16.2/go/vt/discovery/tablets_cache_status.go (about)

     1  package discovery
     2  
     3  import (
     4  	"fmt"
     5  	"html/template"
     6  	"sort"
     7  	"strings"
     8  
     9  	"google.golang.org/protobuf/proto"
    10  
    11  	querypb "vitess.io/vitess/go/vt/proto/query"
    12  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    13  	"vitess.io/vitess/go/vt/topo/topoproto"
    14  )
    15  
    16  // TabletsCacheStatus is the current tablets for a cell/target.
    17  type TabletsCacheStatus struct {
    18  	Cell         string
    19  	Target       *querypb.Target
    20  	TabletsStats TabletStatsList
    21  }
    22  
    23  // TabletStatsList is used for sorting.
    24  type TabletStatsList []*TabletHealth
    25  
    26  // Len is part of sort.Interface.
    27  func (tsl TabletStatsList) Len() int {
    28  	return len(tsl)
    29  }
    30  
    31  // Less is part of sort.Interface
    32  func (tsl TabletStatsList) Less(i, j int) bool {
    33  	name1 := topoproto.TabletAliasString(tsl[i].Tablet.Alias)
    34  	name2 := topoproto.TabletAliasString(tsl[j].Tablet.Alias)
    35  	return name1 < name2
    36  }
    37  
    38  // Swap is part of sort.Interface
    39  func (tsl TabletStatsList) Swap(i, j int) {
    40  	tsl[i], tsl[j] = tsl[j], tsl[i]
    41  }
    42  
    43  func (tsl TabletStatsList) deepEqual(other TabletStatsList) bool {
    44  	if len(tsl) != len(other) {
    45  		return false
    46  	}
    47  	for i, th := range tsl {
    48  		o := other[i]
    49  		if !th.DeepEqual(o) {
    50  			return false
    51  		}
    52  	}
    53  	return true
    54  }
    55  
    56  // StatusAsHTML returns an HTML version of the status.
    57  func (tcs *TabletsCacheStatus) StatusAsHTML() template.HTML {
    58  	tLinks := make([]string, 0, 1)
    59  	if tcs.TabletsStats != nil {
    60  		sort.Sort(tcs.TabletsStats)
    61  	}
    62  	for _, ts := range tcs.TabletsStats {
    63  		color := "green"
    64  		extra := ""
    65  		if ts.LastError != nil {
    66  			color = "red"
    67  			extra = fmt.Sprintf(" (%v)", ts.LastError)
    68  		} else if !ts.Serving {
    69  			color = "red"
    70  			extra = " (Not Serving)"
    71  		} else if ts.Target.TabletType == topodatapb.TabletType_PRIMARY {
    72  			extra = fmt.Sprintf(" (PrimaryTermStartTime: %v)", ts.PrimaryTermStartTime)
    73  		} else {
    74  			extra = fmt.Sprintf(" (RepLag: %v)", ts.Stats.ReplicationLagSeconds)
    75  		}
    76  		name := topoproto.TabletAliasString(ts.Tablet.Alias)
    77  		tLinks = append(tLinks, fmt.Sprintf(`<a href="%s" style="color:%v">%v</a>%v`, ts.getTabletDebugURL(), color, name, extra))
    78  	}
    79  	return template.HTML(strings.Join(tLinks, "<br>"))
    80  }
    81  
    82  func (tcs *TabletsCacheStatus) deepEqual(otcs *TabletsCacheStatus) bool {
    83  	return tcs.Cell == otcs.Cell &&
    84  		proto.Equal(tcs.Target, otcs.Target) &&
    85  		tcs.TabletsStats.deepEqual(otcs.TabletsStats)
    86  }
    87  
    88  // TabletsCacheStatusList is used for sorting.
    89  type TabletsCacheStatusList []*TabletsCacheStatus
    90  
    91  // Len is part of sort.Interface.
    92  func (tcsl TabletsCacheStatusList) Len() int {
    93  	return len(tcsl)
    94  }
    95  
    96  // Less is part of sort.Interface
    97  func (tcsl TabletsCacheStatusList) Less(i, j int) bool {
    98  	return tcsl[i].Cell+"."+tcsl[i].Target.Keyspace+"."+tcsl[i].Target.Shard+"."+string(tcsl[i].Target.TabletType) <
    99  		tcsl[j].Cell+"."+tcsl[j].Target.Keyspace+"."+tcsl[j].Target.Shard+"."+string(tcsl[j].Target.TabletType)
   100  }
   101  
   102  // Swap is part of sort.Interface
   103  func (tcsl TabletsCacheStatusList) Swap(i, j int) {
   104  	tcsl[i], tcsl[j] = tcsl[j], tcsl[i]
   105  }
   106  
   107  func (tcsl TabletsCacheStatusList) deepEqual(other TabletsCacheStatusList) bool {
   108  	if len(tcsl) != len(other) {
   109  		return false
   110  	}
   111  	for i, tcs := range tcsl {
   112  		otcs := other[i]
   113  		if !tcs.deepEqual(otcs) {
   114  			return false
   115  		}
   116  	}
   117  	return true
   118  }