github.com/rohankumardubey/proxyfs@v0.0.0-20210108201508-653efa9ab00e/stats/config.go (about)

     1  package stats
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/swiftstack/ProxyFS/conf"
    10  	"github.com/swiftstack/ProxyFS/trackedlock"
    11  	"github.com/swiftstack/ProxyFS/transitions"
    12  )
    13  
    14  const (
    15  	expectedNumberOfDistinctStatNames = 100
    16  )
    17  
    18  type statStruct struct {
    19  	name      *string
    20  	increment uint64
    21  }
    22  
    23  type statNameLinkStruct struct {
    24  	name string
    25  	next *statNameLinkStruct
    26  }
    27  
    28  type globalsStruct struct {
    29  	trackedlock.Mutex //                     Used only for snapshotting statFullMap
    30  	ipAddr            string
    31  	udpPort           uint16
    32  	tcpPort           uint16
    33  	useUDP            bool   //              Logically useTCP == !useUDP
    34  	connectionType    string //              Either "udp" or "tcp"
    35  	udpLAddr          *net.UDPAddr
    36  	udpRAddr          *net.UDPAddr
    37  	tcpLAddr          *net.TCPAddr
    38  	tcpRAddr          *net.TCPAddr
    39  	bufferLength      uint16
    40  	maxLatency        time.Duration //       Timer should pop in maxLatency/statTree.Len()
    41  	statChan          chan *statStruct
    42  	tickChan          <-chan time.Time
    43  	stopChan          chan bool
    44  	doneChan          chan bool
    45  	statDeltaMap      map[string]uint64 //   Key is stat.name, Value is the sum of all un-sent/accumulated stat.increment's
    46  	statFullMap       map[string]uint64 //   Key is stat.name, Value is the sum of all accumulated stat.increment's
    47  	headStatNameLink  *statNameLinkStruct
    48  	tailStatNameLink  *statNameLinkStruct
    49  }
    50  
    51  var globals globalsStruct
    52  
    53  func init() {
    54  	transitions.Register("stats", &globals)
    55  }
    56  
    57  func (dummy *globalsStruct) Up(confMap conf.ConfMap) (err error) {
    58  	var (
    59  		errFetchingTCPPort error
    60  		errFetchingUDPPort error
    61  	)
    62  
    63  	globals.ipAddr = "localhost" // Hard-coded since we only want to talk to the local StatsD
    64  
    65  	globals.udpPort, errFetchingUDPPort = confMap.FetchOptionValueUint16("Stats", "UDPPort")
    66  	globals.tcpPort, errFetchingTCPPort = confMap.FetchOptionValueUint16("Stats", "TCPPort")
    67  
    68  	if (nil != errFetchingUDPPort) && (nil != errFetchingTCPPort) {
    69  		err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"UDPPort\") failed: %v AND confMap.FetchOptionValueUint16(\"Stats\", \"TCPPort\") failed: %v", errFetchingTCPPort, errFetchingUDPPort)
    70  		return
    71  	}
    72  
    73  	if (nil == errFetchingUDPPort) && (nil == errFetchingTCPPort) {
    74  		err = fmt.Errorf("Only one of [Stats]UDPPort and [Stats]TCPPort may be specified")
    75  		return
    76  	}
    77  
    78  	globals.useUDP = (nil == errFetchingUDPPort)
    79  
    80  	if globals.useUDP {
    81  		globals.udpLAddr, err = net.ResolveUDPAddr("udp", globals.ipAddr+":0")
    82  		if nil != err {
    83  			return
    84  		}
    85  		globals.udpRAddr, err = net.ResolveUDPAddr("udp", globals.ipAddr+":"+strconv.FormatUint(uint64(globals.udpPort), 10))
    86  		if nil != err {
    87  			return
    88  		}
    89  	} else { // globals.useTCP
    90  		globals.tcpLAddr, err = net.ResolveTCPAddr("tcp", globals.ipAddr+":0")
    91  		if nil != err {
    92  			return
    93  		}
    94  		globals.tcpRAddr, err = net.ResolveTCPAddr("tcp", globals.ipAddr+":"+strconv.FormatUint(uint64(globals.tcpPort), 10))
    95  		if nil != err {
    96  			return
    97  		}
    98  	}
    99  
   100  	globals.bufferLength, err = confMap.FetchOptionValueUint16("Stats", "BufferLength")
   101  	if nil != err {
   102  		err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"BufferLength\") failed: %v", err)
   103  		return
   104  	}
   105  
   106  	globals.maxLatency, err = confMap.FetchOptionValueDuration("Stats", "MaxLatency")
   107  	if nil != err {
   108  		err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"MaxLatency\") failed: %v", err)
   109  		return
   110  	}
   111  
   112  	globals.statChan = make(chan *statStruct, globals.bufferLength)
   113  	globals.stopChan = make(chan bool, 1)
   114  	globals.doneChan = make(chan bool, 1)
   115  
   116  	globals.statDeltaMap = make(map[string]uint64, expectedNumberOfDistinctStatNames)
   117  	globals.headStatNameLink = nil
   118  	globals.tailStatNameLink = nil
   119  
   120  	globals.statFullMap = make(map[string]uint64, expectedNumberOfDistinctStatNames)
   121  
   122  	// Start the ticker
   123  	var timeoutDuration time.Duration
   124  	if expectedNumberOfDistinctStatNames > 0 {
   125  		timeoutDuration = globals.maxLatency
   126  	}
   127  	// else our ticker is disabled
   128  	globals.tickChan = time.Tick(timeoutDuration)
   129  
   130  	go sender()
   131  
   132  	err = nil
   133  	return
   134  }
   135  
   136  func (dummy *globalsStruct) VolumeGroupCreated(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) {
   137  	return nil
   138  }
   139  func (dummy *globalsStruct) VolumeGroupMoved(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) {
   140  	return nil
   141  }
   142  func (dummy *globalsStruct) VolumeGroupDestroyed(confMap conf.ConfMap, volumeGroupName string) (err error) {
   143  	return nil
   144  }
   145  func (dummy *globalsStruct) VolumeCreated(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) {
   146  	return nil
   147  }
   148  func (dummy *globalsStruct) VolumeMoved(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) {
   149  	return nil
   150  }
   151  func (dummy *globalsStruct) VolumeDestroyed(confMap conf.ConfMap, volumeName string) (err error) {
   152  	return nil
   153  }
   154  func (dummy *globalsStruct) ServeVolume(confMap conf.ConfMap, volumeName string) (err error) {
   155  	return nil
   156  }
   157  func (dummy *globalsStruct) UnserveVolume(confMap conf.ConfMap, volumeName string) (err error) {
   158  	return nil
   159  }
   160  func (dummy *globalsStruct) VolumeToBeUnserved(confMap conf.ConfMap, volumeName string) (err error) {
   161  	return nil
   162  }
   163  func (dummy *globalsStruct) SignaledStart(confMap conf.ConfMap) (err error) {
   164  	return nil
   165  }
   166  func (dummy *globalsStruct) SignaledFinish(confMap conf.ConfMap) (err error) {
   167  	return nil
   168  }
   169  
   170  func (dummy *globalsStruct) Down(confMap conf.ConfMap) (err error) {
   171  	globals.stopChan <- true
   172  
   173  	_ = <-globals.doneChan
   174  
   175  	globals.statChan = nil
   176  
   177  	err = nil
   178  
   179  	return
   180  }