github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/influxdb/v2/udp.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "io" 6 "net" 7 "time" 8 ) 9 10 const ( 11 // UDPPayloadSize is a reasonable default payload size for UDP packets that 12 // could be travelling over the internet. 13 UDPPayloadSize = 512 14 ) 15 16 // UDPConfig is the config data needed to create a UDP Client. 17 type UDPConfig struct { 18 // Addr should be of the form "host:port" 19 // or "[ipv6-host%zone]:port". 20 Addr string 21 22 // PayloadSize is the maximum size of a UDP client message, optional 23 // Tune this based on your network. Defaults to UDPPayloadSize. 24 PayloadSize int 25 } 26 27 // NewUDPClient returns a client interface for writing to an InfluxDB UDP 28 // service from the given config. 29 func NewUDPClient(conf UDPConfig) (Client, error) { 30 var udpAddr *net.UDPAddr 31 udpAddr, err := net.ResolveUDPAddr("udp", conf.Addr) 32 if err != nil { 33 return nil, err 34 } 35 36 conn, err := net.DialUDP("udp", nil, udpAddr) 37 if err != nil { 38 return nil, err 39 } 40 41 payloadSize := conf.PayloadSize 42 if payloadSize == 0 { 43 payloadSize = UDPPayloadSize 44 } 45 46 return &udpclient{ 47 conn: conn, 48 payloadSize: payloadSize, 49 }, nil 50 } 51 52 // Close releases the udpclient's resources. 53 func (uc *udpclient) Close() error { 54 return uc.conn.Close() 55 } 56 57 type udpclient struct { 58 conn io.WriteCloser 59 payloadSize int 60 } 61 62 func (uc *udpclient) Write(bp BatchPoints) error { 63 var b = make([]byte, 0, uc.payloadSize) // initial buffer size, it will grow as needed 64 var d, _ = time.ParseDuration("1" + bp.Precision()) 65 66 var delayedError error 67 68 var checkBuffer = func(n int) { 69 if len(b) > 0 && len(b)+n > uc.payloadSize { 70 if _, err := uc.conn.Write(b); err != nil { 71 delayedError = err 72 } 73 b = b[:0] 74 } 75 } 76 77 for _, p := range bp.Points() { 78 p.pt.Round(d) 79 pointSize := p.pt.StringSize() + 1 // include newline in size 80 //point := p.pt.RoundedString(d) + "\n" 81 82 checkBuffer(pointSize) 83 84 if p.Time().IsZero() || pointSize <= uc.payloadSize { 85 b = p.pt.AppendString(b) 86 b = append(b, '\n') 87 continue 88 } 89 90 points := p.pt.Split(uc.payloadSize - 1) // account for newline character 91 for _, sp := range points { 92 checkBuffer(sp.StringSize() + 1) 93 b = sp.AppendString(b) 94 b = append(b, '\n') 95 } 96 } 97 98 if len(b) > 0 { 99 if _, err := uc.conn.Write(b); err != nil { 100 return err 101 } 102 } 103 return delayedError 104 } 105 106 func (uc *udpclient) Query(q Query) (*Response, error) { 107 return nil, fmt.Errorf("Querying via UDP is not supported") 108 } 109 110 func (uc *udpclient) Ping(timeout time.Duration) (time.Duration, string, error) { 111 return 0, "", nil 112 }