mirror of
https://github.com/Oxalide/vsphere-influxdb-go.git
synced 2023-10-10 11:36:51 +00:00
add vendoring with go dep
This commit is contained in:
128
vendor/github.com/influxdata/influxdb/services/udp/README.md
generated
vendored
Normal file
128
vendor/github.com/influxdata/influxdb/services/udp/README.md
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
# The UDP Input
|
||||
|
||||
## A note on UDP/IP OS Buffer sizes
|
||||
|
||||
Some OSes (most notably, Linux) place very restricive limits on the performance
|
||||
of UDP protocols. It is _highly_ recommended that you increase these OS limits to
|
||||
at least 25MB before trying to run UDP traffic to your instance.
|
||||
25MB is just a recommendation, and should be adjusted to be inline with your
|
||||
`read-buffer` plugin setting.
|
||||
|
||||
### Linux
|
||||
Check the current UDP/IP receive buffer default and limit by typing the following commands:
|
||||
|
||||
```
|
||||
sysctl net.core.rmem_max
|
||||
sysctl net.core.rmem_default
|
||||
```
|
||||
|
||||
If the values are less than 26214400 bytes (25MB) you should add the following lines to the /etc/sysctl.conf file:
|
||||
|
||||
```
|
||||
net.core.rmem_max=26214400
|
||||
net.core.rmem_default=26214400
|
||||
```
|
||||
|
||||
Changes to /etc/sysctl.conf do not take effect until reboot. To update the values immediately, type the following commands as root:
|
||||
|
||||
```
|
||||
sysctl -w net.core.rmem_max=26214400
|
||||
sysctl -w net.core.rmem_default=26214400
|
||||
```
|
||||
|
||||
### BSD/Darwin
|
||||
|
||||
On BSD/Darwin systems you need to add about a 15% padding to the kernel limit
|
||||
socket buffer. Meaning if you want an 25MB buffer (8388608 bytes) you need to set
|
||||
the kernel limit to `26214400*1.15 = 30146560`. This is not documented anywhere but
|
||||
happens
|
||||
[in the kernel here.](https://github.com/freebsd/freebsd/blob/master/sys/kern/uipc_sockbuf.c#L63-L64)
|
||||
|
||||
Check the current UDP/IP buffer limit by typing the following command:
|
||||
|
||||
```
|
||||
sysctl kern.ipc.maxsockbuf
|
||||
```
|
||||
|
||||
If the value is less than 30146560 bytes you should add the following lines to the /etc/sysctl.conf file (create it if necessary):
|
||||
|
||||
```
|
||||
kern.ipc.maxsockbuf=30146560
|
||||
```
|
||||
|
||||
Changes to /etc/sysctl.conf do not take effect until reboot. To update the values immediately, type the following commands as root:
|
||||
|
||||
```
|
||||
sysctl -w kern.ipc.maxsockbuf=30146560
|
||||
```
|
||||
|
||||
### Using the read-buffer option for the UDP listener
|
||||
|
||||
The `read-buffer` option allows users to set the buffer size for the UDP listener.
|
||||
It Sets the size of the operating system's receive buffer associated with
|
||||
the UDP traffic. Keep in mind that the OS must be able
|
||||
to handle the number set here or the UDP listener will error and exit.
|
||||
|
||||
`read-buffer = 0` means to use the OS default, which is usually too
|
||||
small for high UDP performance.
|
||||
|
||||
## Configuration
|
||||
|
||||
Each UDP input allows the binding address, target database, and target retention policy to be set. If the database does not exist, it will be created automatically when the input is initialized. If the retention policy is not configured, then the default retention policy for the database is used. However if the retention policy is set, the retention policy must be explicitly created. The input will not automatically create it.
|
||||
|
||||
Each UDP input also performs internal batching of the points it receives, as batched writes to the database are more efficient. The default _batch size_ is 1000, _pending batch_ factor is 5, with a _batch timeout_ of 1 second. This means the input will write batches of maximum size 1000, but if a batch has not reached 1000 points within 1 second of the first point being added to a batch, it will emit that batch regardless of size. The pending batch factor controls how many batches can be in memory at once, allowing the input to transmit a batch, while still building other batches.
|
||||
|
||||
## Processing
|
||||
|
||||
The UDP input can receive up to 64KB per read, and splits the received data by newline. Each part is then interpreted as line-protocol encoded points, and parsed accordingly.
|
||||
|
||||
## UDP is connectionless
|
||||
|
||||
Since UDP is a connectionless protocol there is no way to signal to the data source if any error occurs, and if data has even been successfully indexed. This should be kept in mind when deciding if and when to use the UDP input. The built-in UDP statistics are useful for monitoring the UDP inputs.
|
||||
|
||||
## Config Examples
|
||||
|
||||
One UDP listener
|
||||
|
||||
```
|
||||
# influxd.conf
|
||||
...
|
||||
[[udp]]
|
||||
enabled = true
|
||||
bind-address = ":8089" # the bind address
|
||||
database = "telegraf" # Name of the database that will be written to
|
||||
batch-size = 5000 # will flush if this many points get buffered
|
||||
batch-timeout = "1s" # will flush at least this often even if the batch-size is not reached
|
||||
batch-pending = 10 # number of batches that may be pending in memory
|
||||
read-buffer = 0 # UDP read buffer, 0 means to use OS default
|
||||
...
|
||||
```
|
||||
|
||||
Multiple UDP listeners
|
||||
|
||||
```
|
||||
# influxd.conf
|
||||
...
|
||||
[[udp]]
|
||||
# Default UDP for Telegraf
|
||||
enabled = true
|
||||
bind-address = ":8089" # the bind address
|
||||
database = "telegraf" # Name of the database that will be written to
|
||||
batch-size = 5000 # will flush if this many points get buffered
|
||||
batch-timeout = "1s" # will flush at least this often even if the batch-size is not reached
|
||||
batch-pending = 10 # number of batches that may be pending in memory
|
||||
read-buffer = 0 # UDP read buffer size, 0 means to use OS default
|
||||
|
||||
[[udp]]
|
||||
# High-traffic UDP
|
||||
enabled = true
|
||||
bind-address = ":80891" # the bind address
|
||||
database = "mymetrics" # Name of the database that will be written to
|
||||
batch-size = 5000 # will flush if this many points get buffered
|
||||
batch-timeout = "1s" # will flush at least this often even if the batch-size is not reached
|
||||
batch-pending = 100 # number of batches that may be pending in memory
|
||||
read-buffer = 8388608 # (8*1024*1024) UDP read buffer size
|
||||
...
|
||||
```
|
||||
|
||||
|
127
vendor/github.com/influxdata/influxdb/services/udp/config.go
generated
vendored
Normal file
127
vendor/github.com/influxdata/influxdb/services/udp/config.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/monitor/diagnostics"
|
||||
"github.com/influxdata/influxdb/toml"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultBindAddress is the default binding interface if none is specified.
|
||||
DefaultBindAddress = ":8089"
|
||||
|
||||
// DefaultDatabase is the default database for UDP traffic.
|
||||
DefaultDatabase = "udp"
|
||||
|
||||
// DefaultRetentionPolicy is the default retention policy used for writes.
|
||||
DefaultRetentionPolicy = ""
|
||||
|
||||
// DefaultBatchSize is the default UDP batch size.
|
||||
DefaultBatchSize = 5000
|
||||
|
||||
// DefaultBatchPending is the default number of pending UDP batches.
|
||||
DefaultBatchPending = 10
|
||||
|
||||
// DefaultBatchTimeout is the default UDP batch timeout.
|
||||
DefaultBatchTimeout = time.Second
|
||||
|
||||
// DefaultPrecision is the default time precision used for UDP services.
|
||||
DefaultPrecision = "n"
|
||||
|
||||
// DefaultReadBuffer is the default buffer size for the UDP listener.
|
||||
// Sets the size of the operating system's receive buffer associated with
|
||||
// the UDP traffic. Keep in mind that the OS must be able
|
||||
// to handle the number set here or the UDP listener will error and exit.
|
||||
//
|
||||
// DefaultReadBuffer = 0 means to use the OS default, which is usually too
|
||||
// small for high UDP performance.
|
||||
//
|
||||
// Increasing OS buffer limits:
|
||||
// Linux: sudo sysctl -w net.core.rmem_max=<read-buffer>
|
||||
// BSD/Darwin: sudo sysctl -w kern.ipc.maxsockbuf=<read-buffer>
|
||||
DefaultReadBuffer = 0
|
||||
)
|
||||
|
||||
// Config holds various configuration settings for the UDP listener.
|
||||
type Config struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
BindAddress string `toml:"bind-address"`
|
||||
|
||||
Database string `toml:"database"`
|
||||
RetentionPolicy string `toml:"retention-policy"`
|
||||
BatchSize int `toml:"batch-size"`
|
||||
BatchPending int `toml:"batch-pending"`
|
||||
ReadBuffer int `toml:"read-buffer"`
|
||||
BatchTimeout toml.Duration `toml:"batch-timeout"`
|
||||
Precision string `toml:"precision"`
|
||||
}
|
||||
|
||||
// NewConfig returns a new instance of Config with defaults.
|
||||
func NewConfig() Config {
|
||||
return Config{
|
||||
BindAddress: DefaultBindAddress,
|
||||
Database: DefaultDatabase,
|
||||
RetentionPolicy: DefaultRetentionPolicy,
|
||||
BatchSize: DefaultBatchSize,
|
||||
BatchPending: DefaultBatchPending,
|
||||
BatchTimeout: toml.Duration(DefaultBatchTimeout),
|
||||
}
|
||||
}
|
||||
|
||||
// WithDefaults takes the given config and returns a new config with any required
|
||||
// default values set.
|
||||
func (c *Config) WithDefaults() *Config {
|
||||
d := *c
|
||||
if d.Database == "" {
|
||||
d.Database = DefaultDatabase
|
||||
}
|
||||
if d.BatchSize == 0 {
|
||||
d.BatchSize = DefaultBatchSize
|
||||
}
|
||||
if d.BatchPending == 0 {
|
||||
d.BatchPending = DefaultBatchPending
|
||||
}
|
||||
if d.BatchTimeout == 0 {
|
||||
d.BatchTimeout = toml.Duration(DefaultBatchTimeout)
|
||||
}
|
||||
if d.Precision == "" {
|
||||
d.Precision = DefaultPrecision
|
||||
}
|
||||
if d.ReadBuffer == 0 {
|
||||
d.ReadBuffer = DefaultReadBuffer
|
||||
}
|
||||
return &d
|
||||
}
|
||||
|
||||
// Configs wraps a slice of Config to aggregate diagnostics.
|
||||
type Configs []Config
|
||||
|
||||
// Diagnostics returns one set of diagnostics for all of the Configs.
|
||||
func (c Configs) Diagnostics() (*diagnostics.Diagnostics, error) {
|
||||
d := &diagnostics.Diagnostics{
|
||||
Columns: []string{"enabled", "bind-address", "database", "retention-policy", "batch-size", "batch-pending", "batch-timeout"},
|
||||
}
|
||||
|
||||
for _, cc := range c {
|
||||
if !cc.Enabled {
|
||||
d.AddRow([]interface{}{false})
|
||||
continue
|
||||
}
|
||||
|
||||
r := []interface{}{true, cc.BindAddress, cc.Database, cc.RetentionPolicy, cc.BatchSize, cc.BatchPending, cc.BatchTimeout}
|
||||
d.AddRow(r)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Enabled returns true if any underlying Config is Enabled.
|
||||
func (c Configs) Enabled() bool {
|
||||
for _, cc := range c {
|
||||
if cc.Enabled {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
43
vendor/github.com/influxdata/influxdb/services/udp/config_test.go
generated
vendored
Normal file
43
vendor/github.com/influxdata/influxdb/services/udp/config_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package udp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/influxdata/influxdb/services/udp"
|
||||
)
|
||||
|
||||
func TestConfig_Parse(t *testing.T) {
|
||||
// Parse configuration.
|
||||
var c udp.Config
|
||||
if _, err := toml.Decode(`
|
||||
enabled = true
|
||||
bind-address = ":4444"
|
||||
database = "awesomedb"
|
||||
retention-policy = "awesomerp"
|
||||
batch-size = 100
|
||||
batch-pending = 9
|
||||
batch-timeout = "10ms"
|
||||
udp-payload-size = 1500
|
||||
`, &c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Validate configuration.
|
||||
if c.Enabled != true {
|
||||
t.Fatalf("unexpected enabled: %v", c.Enabled)
|
||||
} else if c.BindAddress != ":4444" {
|
||||
t.Fatalf("unexpected bind address: %s", c.BindAddress)
|
||||
} else if c.Database != "awesomedb" {
|
||||
t.Fatalf("unexpected database: %s", c.Database)
|
||||
} else if c.RetentionPolicy != "awesomerp" {
|
||||
t.Fatalf("unexpected retention policy: %s", c.RetentionPolicy)
|
||||
} else if c.BatchSize != 100 {
|
||||
t.Fatalf("unexpected batch size: %d", c.BatchSize)
|
||||
} else if c.BatchPending != 9 {
|
||||
t.Fatalf("unexpected batch pending: %d", c.BatchPending)
|
||||
} else if time.Duration(c.BatchTimeout) != (10 * time.Millisecond) {
|
||||
t.Fatalf("unexpected batch timeout: %v", c.BatchTimeout)
|
||||
}
|
||||
}
|
300
vendor/github.com/influxdata/influxdb/services/udp/service.go
generated
vendored
Normal file
300
vendor/github.com/influxdata/influxdb/services/udp/service.go
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
// Package udp provides the UDP input service for InfluxDB.
|
||||
package udp // import "github.com/influxdata/influxdb/services/udp"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/models"
|
||||
"github.com/influxdata/influxdb/services/meta"
|
||||
"github.com/influxdata/influxdb/tsdb"
|
||||
"github.com/uber-go/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
// Arbitrary, testing indicated that this doesn't typically get over 10
|
||||
parserChanLen = 1000
|
||||
|
||||
// MaxUDPPayload is largest payload size the UDP service will accept.
|
||||
MaxUDPPayload = 64 * 1024
|
||||
)
|
||||
|
||||
// statistics gathered by the UDP package.
|
||||
const (
|
||||
statPointsReceived = "pointsRx"
|
||||
statBytesReceived = "bytesRx"
|
||||
statPointsParseFail = "pointsParseFail"
|
||||
statReadFail = "readFail"
|
||||
statBatchesTransmitted = "batchesTx"
|
||||
statPointsTransmitted = "pointsTx"
|
||||
statBatchesTransmitFail = "batchesTxFail"
|
||||
)
|
||||
|
||||
// Service is a UDP service that will listen for incoming packets of line protocol.
|
||||
type Service struct {
|
||||
conn *net.UDPConn
|
||||
addr *net.UDPAddr
|
||||
wg sync.WaitGroup
|
||||
|
||||
mu sync.RWMutex
|
||||
ready bool // Has the required database been created?
|
||||
done chan struct{} // Is the service closing or closed?
|
||||
|
||||
parserChan chan []byte
|
||||
batcher *tsdb.PointBatcher
|
||||
config Config
|
||||
|
||||
PointsWriter interface {
|
||||
WritePointsPrivileged(database, retentionPolicy string, consistencyLevel models.ConsistencyLevel, points []models.Point) error
|
||||
}
|
||||
|
||||
MetaClient interface {
|
||||
CreateDatabase(name string) (*meta.DatabaseInfo, error)
|
||||
}
|
||||
|
||||
Logger zap.Logger
|
||||
stats *Statistics
|
||||
defaultTags models.StatisticTags
|
||||
}
|
||||
|
||||
// NewService returns a new instance of Service.
|
||||
func NewService(c Config) *Service {
|
||||
d := *c.WithDefaults()
|
||||
return &Service{
|
||||
config: d,
|
||||
parserChan: make(chan []byte, parserChanLen),
|
||||
batcher: tsdb.NewPointBatcher(d.BatchSize, d.BatchPending, time.Duration(d.BatchTimeout)),
|
||||
Logger: zap.New(zap.NullEncoder()),
|
||||
stats: &Statistics{},
|
||||
defaultTags: models.StatisticTags{"bind": d.BindAddress},
|
||||
}
|
||||
}
|
||||
|
||||
// Open starts the service.
|
||||
func (s *Service) Open() (err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if !s.closed() {
|
||||
return nil // Already open.
|
||||
}
|
||||
s.done = make(chan struct{})
|
||||
|
||||
if s.config.BindAddress == "" {
|
||||
return errors.New("bind address has to be specified in config")
|
||||
}
|
||||
if s.config.Database == "" {
|
||||
return errors.New("database has to be specified in config")
|
||||
}
|
||||
|
||||
s.addr, err = net.ResolveUDPAddr("udp", s.config.BindAddress)
|
||||
if err != nil {
|
||||
s.Logger.Info(fmt.Sprintf("Failed to resolve UDP address %s: %s", s.config.BindAddress, err))
|
||||
return err
|
||||
}
|
||||
|
||||
s.conn, err = net.ListenUDP("udp", s.addr)
|
||||
if err != nil {
|
||||
s.Logger.Info(fmt.Sprintf("Failed to set up UDP listener at address %s: %s", s.addr, err))
|
||||
return err
|
||||
}
|
||||
|
||||
if s.config.ReadBuffer != 0 {
|
||||
err = s.conn.SetReadBuffer(s.config.ReadBuffer)
|
||||
if err != nil {
|
||||
s.Logger.Info(fmt.Sprintf("Failed to set UDP read buffer to %d: %s",
|
||||
s.config.ReadBuffer, err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s.Logger.Info(fmt.Sprintf("Started listening on UDP: %s", s.config.BindAddress))
|
||||
|
||||
s.wg.Add(3)
|
||||
go s.serve()
|
||||
go s.parser()
|
||||
go s.writer()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Statistics maintains statistics for the UDP service.
|
||||
type Statistics struct {
|
||||
PointsReceived int64
|
||||
BytesReceived int64
|
||||
PointsParseFail int64
|
||||
ReadFail int64
|
||||
BatchesTransmitted int64
|
||||
PointsTransmitted int64
|
||||
BatchesTransmitFail int64
|
||||
}
|
||||
|
||||
// Statistics returns statistics for periodic monitoring.
|
||||
func (s *Service) Statistics(tags map[string]string) []models.Statistic {
|
||||
return []models.Statistic{{
|
||||
Name: "udp",
|
||||
Tags: s.defaultTags.Merge(tags),
|
||||
Values: map[string]interface{}{
|
||||
statPointsReceived: atomic.LoadInt64(&s.stats.PointsReceived),
|
||||
statBytesReceived: atomic.LoadInt64(&s.stats.BytesReceived),
|
||||
statPointsParseFail: atomic.LoadInt64(&s.stats.PointsParseFail),
|
||||
statReadFail: atomic.LoadInt64(&s.stats.ReadFail),
|
||||
statBatchesTransmitted: atomic.LoadInt64(&s.stats.BatchesTransmitted),
|
||||
statPointsTransmitted: atomic.LoadInt64(&s.stats.PointsTransmitted),
|
||||
statBatchesTransmitFail: atomic.LoadInt64(&s.stats.BatchesTransmitFail),
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func (s *Service) writer() {
|
||||
defer s.wg.Done()
|
||||
|
||||
for {
|
||||
select {
|
||||
case batch := <-s.batcher.Out():
|
||||
// Will attempt to create database if not yet created.
|
||||
if err := s.createInternalStorage(); err != nil {
|
||||
s.Logger.Info(fmt.Sprintf("Required database %s does not yet exist: %s", s.config.Database, err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.PointsWriter.WritePointsPrivileged(s.config.Database, s.config.RetentionPolicy, models.ConsistencyLevelAny, batch); err == nil {
|
||||
atomic.AddInt64(&s.stats.BatchesTransmitted, 1)
|
||||
atomic.AddInt64(&s.stats.PointsTransmitted, int64(len(batch)))
|
||||
} else {
|
||||
s.Logger.Info(fmt.Sprintf("failed to write point batch to database %q: %s", s.config.Database, err))
|
||||
atomic.AddInt64(&s.stats.BatchesTransmitFail, 1)
|
||||
}
|
||||
|
||||
case <-s.done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) serve() {
|
||||
defer s.wg.Done()
|
||||
|
||||
buf := make([]byte, MaxUDPPayload)
|
||||
s.batcher.Start()
|
||||
for {
|
||||
select {
|
||||
case <-s.done:
|
||||
// We closed the connection, time to go.
|
||||
return
|
||||
default:
|
||||
// Keep processing.
|
||||
n, _, err := s.conn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
atomic.AddInt64(&s.stats.ReadFail, 1)
|
||||
s.Logger.Info(fmt.Sprintf("Failed to read UDP message: %s", err))
|
||||
continue
|
||||
}
|
||||
atomic.AddInt64(&s.stats.BytesReceived, int64(n))
|
||||
|
||||
bufCopy := make([]byte, n)
|
||||
copy(bufCopy, buf[:n])
|
||||
s.parserChan <- bufCopy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) parser() {
|
||||
defer s.wg.Done()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.done:
|
||||
return
|
||||
case buf := <-s.parserChan:
|
||||
points, err := models.ParsePointsWithPrecision(buf, time.Now().UTC(), s.config.Precision)
|
||||
if err != nil {
|
||||
atomic.AddInt64(&s.stats.PointsParseFail, 1)
|
||||
s.Logger.Info(fmt.Sprintf("Failed to parse points: %s", err))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, point := range points {
|
||||
s.batcher.In() <- point
|
||||
}
|
||||
atomic.AddInt64(&s.stats.PointsReceived, int64(len(points)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes the service and the underlying listener.
|
||||
func (s *Service) Close() error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.closed() {
|
||||
return nil // Already closed.
|
||||
}
|
||||
close(s.done)
|
||||
|
||||
if s.conn != nil {
|
||||
s.conn.Close()
|
||||
}
|
||||
|
||||
s.batcher.Flush()
|
||||
s.wg.Wait()
|
||||
|
||||
// Release all remaining resources.
|
||||
s.done = nil
|
||||
s.conn = nil
|
||||
|
||||
s.Logger.Info("Service closed")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Closed returns true if the service is currently closed.
|
||||
func (s *Service) Closed() bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.closed()
|
||||
}
|
||||
|
||||
func (s *Service) closed() bool {
|
||||
select {
|
||||
case <-s.done:
|
||||
// Service is closing.
|
||||
return true
|
||||
default:
|
||||
}
|
||||
return s.done == nil
|
||||
}
|
||||
|
||||
// createInternalStorage ensures that the required database has been created.
|
||||
func (s *Service) createInternalStorage() error {
|
||||
s.mu.RLock()
|
||||
ready := s.ready
|
||||
s.mu.RUnlock()
|
||||
if ready {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := s.MetaClient.CreateDatabase(s.config.Database); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The service is now ready.
|
||||
s.mu.Lock()
|
||||
s.ready = true
|
||||
s.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithLogger sets the logger on the service.
|
||||
func (s *Service) WithLogger(log zap.Logger) {
|
||||
s.Logger = log.With(zap.String("service", "udp"))
|
||||
}
|
||||
|
||||
// Addr returns the listener's address.
|
||||
func (s *Service) Addr() net.Addr {
|
||||
return s.addr
|
||||
}
|
160
vendor/github.com/influxdata/influxdb/services/udp/service_test.go
generated
vendored
Normal file
160
vendor/github.com/influxdata/influxdb/services/udp/service_test.go
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/internal"
|
||||
"github.com/influxdata/influxdb/models"
|
||||
"github.com/influxdata/influxdb/services/meta"
|
||||
"github.com/uber-go/zap"
|
||||
)
|
||||
|
||||
func TestService_OpenClose(t *testing.T) {
|
||||
service := NewTestService(nil)
|
||||
|
||||
// Closing a closed service is fine.
|
||||
if err := service.Service.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Closing a closed service again is fine.
|
||||
if err := service.Service.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := service.Service.Open(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Opening an already open service is fine.
|
||||
if err := service.Service.Open(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Reopening a previously opened service is fine.
|
||||
if err := service.Service.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := service.Service.Open(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Tidy up.
|
||||
if err := service.Service.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_CreatesDatabase(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := NewTestService(nil)
|
||||
s.WritePointsFn = func(string, string, models.ConsistencyLevel, []models.Point) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
called := make(chan struct{})
|
||||
s.MetaClient.CreateDatabaseFn = func(name string) (*meta.DatabaseInfo, error) {
|
||||
if name != s.Config.Database {
|
||||
t.Errorf("\n\texp = %s\n\tgot = %s\n", s.Config.Database, name)
|
||||
}
|
||||
// Allow some time for the caller to return and the ready status to
|
||||
// be set.
|
||||
time.AfterFunc(10*time.Millisecond, func() { called <- struct{}{} })
|
||||
return nil, errors.New("an error")
|
||||
}
|
||||
|
||||
if err := s.Service.Open(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
points, err := models.ParsePointsString(`cpu value=1`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s.Service.batcher.In() <- points[0] // Send a point.
|
||||
s.Service.batcher.Flush()
|
||||
select {
|
||||
case <-called:
|
||||
// OK
|
||||
case <-time.NewTimer(5 * time.Second).C:
|
||||
t.Fatal("Service should have attempted to create database")
|
||||
}
|
||||
|
||||
// ready status should not have been switched due to meta client error.
|
||||
s.Service.mu.RLock()
|
||||
ready := s.Service.ready
|
||||
s.Service.mu.RUnlock()
|
||||
|
||||
if got, exp := ready, false; got != exp {
|
||||
t.Fatalf("got %v, expected %v", got, exp)
|
||||
}
|
||||
|
||||
// This time MC won't cause an error.
|
||||
s.MetaClient.CreateDatabaseFn = func(name string) (*meta.DatabaseInfo, error) {
|
||||
// Allow some time for the caller to return and the ready status to
|
||||
// be set.
|
||||
time.AfterFunc(10*time.Millisecond, func() { called <- struct{}{} })
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
s.Service.batcher.In() <- points[0] // Send a point.
|
||||
s.Service.batcher.Flush()
|
||||
select {
|
||||
case <-called:
|
||||
// OK
|
||||
case <-time.NewTimer(5 * time.Second).C:
|
||||
t.Fatal("Service should have attempted to create database")
|
||||
}
|
||||
|
||||
// ready status should now be true.
|
||||
s.Service.mu.RLock()
|
||||
ready = s.Service.ready
|
||||
s.Service.mu.RUnlock()
|
||||
|
||||
if got, exp := ready, true; got != exp {
|
||||
t.Fatalf("got %v, expected %v", got, exp)
|
||||
}
|
||||
|
||||
s.Service.Close()
|
||||
}
|
||||
|
||||
type TestService struct {
|
||||
Service *Service
|
||||
Config Config
|
||||
MetaClient *internal.MetaClientMock
|
||||
WritePointsFn func(database, retentionPolicy string, consistencyLevel models.ConsistencyLevel, points []models.Point) error
|
||||
}
|
||||
|
||||
func NewTestService(c *Config) *TestService {
|
||||
if c == nil {
|
||||
defaultC := NewConfig()
|
||||
c = &defaultC
|
||||
}
|
||||
|
||||
service := &TestService{
|
||||
Service: NewService(*c),
|
||||
Config: *c,
|
||||
MetaClient: &internal.MetaClientMock{},
|
||||
}
|
||||
|
||||
if testing.Verbose() {
|
||||
service.Service.WithLogger(zap.New(
|
||||
zap.NewTextEncoder(),
|
||||
zap.Output(os.Stderr),
|
||||
))
|
||||
}
|
||||
|
||||
service.Service.MetaClient = service.MetaClient
|
||||
service.Service.PointsWriter = service
|
||||
return service
|
||||
}
|
||||
|
||||
func (s *TestService) WritePointsPrivileged(database, retentionPolicy string, consistencyLevel models.ConsistencyLevel, points []models.Point) error {
|
||||
return s.WritePointsFn(database, retentionPolicy, consistencyLevel, points)
|
||||
}
|
Reference in New Issue
Block a user