influxdb/api/graphite/graphite_metric.go

52 lines
1.2 KiB
Go
Raw Normal View History

2014-03-04 01:52:57 +00:00
package graphite
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
type GraphiteMetric struct {
name string
isInt bool
integerValue int64
floatValue float64
timestamp int64
}
graphite ingest write data in batches to coordinator Close #644 This commit also include lots of cleanup related to start up and shutting down as well as logging. Below is an explanation of how the api starts up and shuts down. It also covers the error conditions and how they are handled. networking/goroutine fixes * break from TCP Accept() loop when connection closed, which was preventing shutdown to proceed * make sure that UDP functionality doesn't write to writeSeries channel after it has been closed. * clearer, more specific shutdown message in particular: * self.writers allows us to make sure things writing to writeSeries are done (they do blocking calls to handleMessage()) whether udp or tcp * self.connClosed lets us break from the Accept() loop, see http://zhen.org/blog/graceful-shutdown-of-go-net-dot-listeners/ (quit channel) * shutdown channel is now allCommitted things can get a little complicated, so here's a little schematic of how the functions and their logic relate: indent for a call out or important code within. everything shown as one nested tree server.go go ListenAndServe go committer reads from self.writeSeries until closed, then writes to self.allCommitted Serve for { Accept, breaks if err + connClosed self.writers.Add() go handleClient for { handleMessage reads until err and writes to self.writeSeries until read failed reads until EOF, ignores other handleMessage errors } conn.Close() self.writers.Done() } self.writers.Wait() close(self.writeSeries) Close() close(self.connClosed) self.conn.Close() wants confirmation on allCommitted channel; [timeout] returns within 5s
2014-04-11 12:25:09 +00:00
// returns err == io.EOF when we hit EOF without any further data
2014-03-04 01:52:57 +00:00
func (self *GraphiteMetric) Read(reader *bufio.Reader) error {
buf, err := reader.ReadBytes('\n')
str := strings.TrimSpace(string(buf))
if err != nil {
if err != io.EOF {
graphite ingest write data in batches to coordinator Close #644 This commit also include lots of cleanup related to start up and shutting down as well as logging. Below is an explanation of how the api starts up and shuts down. It also covers the error conditions and how they are handled. networking/goroutine fixes * break from TCP Accept() loop when connection closed, which was preventing shutdown to proceed * make sure that UDP functionality doesn't write to writeSeries channel after it has been closed. * clearer, more specific shutdown message in particular: * self.writers allows us to make sure things writing to writeSeries are done (they do blocking calls to handleMessage()) whether udp or tcp * self.connClosed lets us break from the Accept() loop, see http://zhen.org/blog/graceful-shutdown-of-go-net-dot-listeners/ (quit channel) * shutdown channel is now allCommitted things can get a little complicated, so here's a little schematic of how the functions and their logic relate: indent for a call out or important code within. everything shown as one nested tree server.go go ListenAndServe go committer reads from self.writeSeries until closed, then writes to self.allCommitted Serve for { Accept, breaks if err + connClosed self.writers.Add() go handleClient for { handleMessage reads until err and writes to self.writeSeries until read failed reads until EOF, ignores other handleMessage errors } conn.Close() self.writers.Done() } self.writers.Wait() close(self.writeSeries) Close() close(self.connClosed) self.conn.Close() wants confirmation on allCommitted channel; [timeout] returns within 5s
2014-04-11 12:25:09 +00:00
return fmt.Errorf("connection closed uncleanly/broken: %s\n", err.Error())
2014-03-04 01:52:57 +00:00
}
graphite ingest write data in batches to coordinator Close #644 This commit also include lots of cleanup related to start up and shutting down as well as logging. Below is an explanation of how the api starts up and shuts down. It also covers the error conditions and how they are handled. networking/goroutine fixes * break from TCP Accept() loop when connection closed, which was preventing shutdown to proceed * make sure that UDP functionality doesn't write to writeSeries channel after it has been closed. * clearer, more specific shutdown message in particular: * self.writers allows us to make sure things writing to writeSeries are done (they do blocking calls to handleMessage()) whether udp or tcp * self.connClosed lets us break from the Accept() loop, see http://zhen.org/blog/graceful-shutdown-of-go-net-dot-listeners/ (quit channel) * shutdown channel is now allCommitted things can get a little complicated, so here's a little schematic of how the functions and their logic relate: indent for a call out or important code within. everything shown as one nested tree server.go go ListenAndServe go committer reads from self.writeSeries until closed, then writes to self.allCommitted Serve for { Accept, breaks if err + connClosed self.writers.Add() go handleClient for { handleMessage reads until err and writes to self.writeSeries until read failed reads until EOF, ignores other handleMessage errors } conn.Close() self.writers.Done() } self.writers.Wait() close(self.writeSeries) Close() close(self.connClosed) self.conn.Close() wants confirmation on allCommitted channel; [timeout] returns within 5s
2014-04-11 12:25:09 +00:00
if str == "" {
return err
2014-03-04 01:52:57 +00:00
}
graphite ingest write data in batches to coordinator Close #644 This commit also include lots of cleanup related to start up and shutting down as well as logging. Below is an explanation of how the api starts up and shuts down. It also covers the error conditions and how they are handled. networking/goroutine fixes * break from TCP Accept() loop when connection closed, which was preventing shutdown to proceed * make sure that UDP functionality doesn't write to writeSeries channel after it has been closed. * clearer, more specific shutdown message in particular: * self.writers allows us to make sure things writing to writeSeries are done (they do blocking calls to handleMessage()) whether udp or tcp * self.connClosed lets us break from the Accept() loop, see http://zhen.org/blog/graceful-shutdown-of-go-net-dot-listeners/ (quit channel) * shutdown channel is now allCommitted things can get a little complicated, so here's a little schematic of how the functions and their logic relate: indent for a call out or important code within. everything shown as one nested tree server.go go ListenAndServe go committer reads from self.writeSeries until closed, then writes to self.allCommitted Serve for { Accept, breaks if err + connClosed self.writers.Add() go handleClient for { handleMessage reads until err and writes to self.writeSeries until read failed reads until EOF, ignores other handleMessage errors } conn.Close() self.writers.Done() } self.writers.Wait() close(self.writeSeries) Close() close(self.connClosed) self.conn.Close() wants confirmation on allCommitted channel; [timeout] returns within 5s
2014-04-11 12:25:09 +00:00
// else we got EOF but also data, so just try to process it as valid data
2014-03-04 01:52:57 +00:00
}
elements := strings.Fields(str)
2014-03-04 01:52:57 +00:00
if len(elements) != 3 {
return fmt.Errorf("Received '%s' which doesn't have three fields", str)
}
self.name = elements[0]
self.floatValue, err = strconv.ParseFloat(elements[1], 64)
if err != nil {
return err
}
if i := int64(self.floatValue); float64(i) == self.floatValue {
self.isInt = true
self.integerValue = int64(self.floatValue)
}
timestamp, err := strconv.ParseUint(elements[2], 10, 32)
if err != nil {
return err
}
self.timestamp = int64(timestamp * 1000000)
return nil
}