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  }