vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletserver/throttle/mysql/instance_key.go (about) 1 /* 2 Copyright 2015 Shlomi Noach, courtesy Booking.com 3 See https://github.com/github/freno/blob/master/LICENSE 4 */ 5 6 package mysql 7 8 import ( 9 "fmt" 10 "strconv" 11 "strings" 12 ) 13 14 // InstanceKey is an instance indicator, identified by hostname and port 15 type InstanceKey struct { 16 Hostname string 17 Port int 18 } 19 20 // SelfInstanceKey is a special indicator for "this instance", e.g. denoting the MySQL server associated with local tablet 21 // The values of this key are immaterial and are intentionally descriptive 22 var SelfInstanceKey = &InstanceKey{Hostname: "(self)", Port: 1} 23 24 // newRawInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 25 // It expects such format and returns with error if input differs in format 26 func newRawInstanceKey(hostPort string) (*InstanceKey, error) { 27 tokens := strings.SplitN(hostPort, ":", 2) 28 if len(tokens) != 2 { 29 return nil, fmt.Errorf("Cannot parse InstanceKey from %s. Expected format is host:port", hostPort) 30 } 31 instanceKey := &InstanceKey{Hostname: tokens[0]} 32 var err error 33 if instanceKey.Port, err = strconv.Atoi(tokens[1]); err != nil { 34 return instanceKey, fmt.Errorf("Invalid port: %s", tokens[1]) 35 } 36 37 return instanceKey, nil 38 } 39 40 // ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 or some.hostname 41 // `defaultPort` is used if `hostPort` does not include a port. 42 func ParseInstanceKey(hostPort string, defaultPort int) (*InstanceKey, error) { 43 if !strings.Contains(hostPort, ":") { 44 return &InstanceKey{Hostname: hostPort, Port: defaultPort}, nil 45 } 46 return newRawInstanceKey(hostPort) 47 } 48 49 // Equals tests equality between this key and another key 50 func (i *InstanceKey) Equals(other *InstanceKey) bool { 51 if other == nil { 52 return false 53 } 54 return i.Hostname == other.Hostname && i.Port == other.Port 55 } 56 57 // SmallerThan returns true if this key is dictionary-smaller than another. 58 // This is used for consistent sorting/ordering; there's nothing magical about it. 59 func (i *InstanceKey) SmallerThan(other *InstanceKey) bool { 60 if i.Hostname < other.Hostname { 61 return true 62 } 63 if i.Hostname == other.Hostname && i.Port < other.Port { 64 return true 65 } 66 return false 67 } 68 69 // IsValid uses simple heuristics to see whether this key represents an actual instance 70 func (i *InstanceKey) IsValid() bool { 71 if i.Hostname == "_" { 72 return false 73 } 74 return len(i.Hostname) > 0 && i.Port > 0 75 } 76 77 // IsSelf checks if this is the special "self" instance key 78 func (i *InstanceKey) IsSelf() bool { 79 if SelfInstanceKey == i { 80 return true 81 } 82 return SelfInstanceKey.Equals(i) 83 } 84 85 // StringCode returns an official string representation of this key 86 func (i *InstanceKey) StringCode() string { 87 return fmt.Sprintf("%s:%d", i.Hostname, i.Port) 88 } 89 90 // DisplayString returns a user-friendly string representation of this key 91 func (i *InstanceKey) DisplayString() string { 92 return i.StringCode() 93 } 94 95 // String returns a user-friendly string representation of this key 96 func (i InstanceKey) String() string { 97 return i.StringCode() 98 }