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  }