Beispiel #1
0
func TestQueryManager_Interrupt(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	closing := make(chan struct{})
	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:       q,
		Database:    `mydb`,
		InterruptCh: closing,
	}

	_, ch, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}
	close(closing)

	select {
	case <-ch:
	case <-time.After(100 * time.Millisecond):
		t.Error("interrupting the query did not close the channel after 100 milliseconds")
	}
}
Beispiel #2
0
func TestQueryManager_KillQuery(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
	}

	qid, ch, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}
	qm.KillQuery(qid)

	select {
	case <-ch:
	case <-time.After(100 * time.Millisecond):
		t.Error("detaching the query did not close the channel after 100 milliseconds")
	}

	if err := qm.KillQuery(qid); err == nil || err.Error() != fmt.Sprintf("no such query id: %d", qid) {
		t.Errorf("incorrect error detaching query, got %s", err)
	}
}
func TestQueryManager_Close(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
	}

	_, ch, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}
	qm.Close()

	select {
	case <-ch:
	case <-time.After(100 * time.Millisecond):
		t.Error("closing the query manager did not kill the query after 100 milliseconds")
	}

	_, _, err = qm.AttachQuery(&params)
	if err == nil || err != influxql.ErrQueryManagerShutdown {
		t.Errorf("unexpected error: %s", err)
	}
}
Beispiel #4
0
func TestQueryManager_Queries(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
	}

	qid, _, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}

	queries := qm.Queries()
	if len(queries) != 1 {
		t.Errorf("expected 1 query, got %d", len(queries))
	} else {
		qi := queries[0]
		if qi.ID != qid {
			t.Errorf("query id: exp=%d got=%d", qid, qi.ID)
		}
		if qi.Query != `SELECT count(value) FROM cpu` {
			t.Errorf("query id: incorrect query string, got '%s'", qi.Query)
		}
		if qi.Database != "mydb" {
			t.Errorf("query id: incorrect database, got %s", qi.Database)
		}
	}

	qm.KillQuery(qid)
	queries = qm.Queries()
	if len(queries) != 0 {
		t.Errorf("expected 0 queries, got %d", len(queries))
	}
}
Beispiel #5
0
func TestQueryManager_AttachQuery(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
	}

	qid, _, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}
	defer qm.KillQuery(qid)

	if qid != 1 {
		t.Errorf("incorrect query id: exp=1 got=%d", qid)
	}
}
Beispiel #6
0
func TestQueryManager_Limit_ConcurrentQueries(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(1)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
	}

	qid, _, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}
	defer qm.KillQuery(qid)

	_, _, err = qm.AttachQuery(&params)
	if err == nil || err != influxql.ErrMaxConcurrentQueriesReached {
		t.Errorf("unexpected error: %s", err)
	}
}
Beispiel #7
0
func TestQueryManager_Limit_Timeout(t *testing.T) {
	q, err := influxql.ParseQuery(`SELECT count(value) FROM cpu`)
	if err != nil {
		t.Fatal(err)
	}

	qm := influxql.DefaultQueryManager(0)
	params := influxql.QueryParams{
		Query:    q,
		Database: `mydb`,
		Timeout:  time.Nanosecond,
	}

	_, ch, err := qm.AttachQuery(&params)
	if err != nil {
		t.Fatal(err)
	}

	select {
	case <-ch:
	case <-time.After(time.Millisecond):
		t.Errorf("timeout has not killed the query")
	}
}
Beispiel #8
0
// NewServer returns a new instance of Server built from a config.
func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) {
	// We need to ensure that a meta directory always exists even if
	// we don't start the meta store.  node.json is always stored under
	// the meta directory.
	if err := os.MkdirAll(c.Meta.Dir, 0777); err != nil {
		return nil, fmt.Errorf("mkdir all: %s", err)
	}

	// 0.10-rc1 and prior would sometimes put the node.json at the root
	// dir which breaks backup/restore and restarting nodes.  This moves
	// the file from the root so it's always under the meta dir.
	oldPath := filepath.Join(filepath.Dir(c.Meta.Dir), "node.json")
	newPath := filepath.Join(c.Meta.Dir, "node.json")

	if _, err := os.Stat(oldPath); err == nil {
		if err := os.Rename(oldPath, newPath); err != nil {
			return nil, err
		}
	}

	_, err := influxdb.LoadNode(c.Meta.Dir)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}
	}

	// In 0.10.0 bind-address got moved to the top level. Check
	// The old location to keep things backwards compatible
	bind := c.BindAddress

	s := &Server{
		buildInfo: *buildInfo,
		err:       make(chan error),
		closing:   make(chan struct{}),

		BindAddress: bind,

		MetaClient: meta.NewClient(c.Meta),

		Monitor: monitor.New(c.Monitor),

		reportingDisabled: c.ReportingDisabled,

		httpAPIAddr: c.HTTPD.BindAddress,
		httpUseTLS:  c.HTTPD.HTTPSEnabled,
		tcpAddr:     bind,

		config: c,
	}

	if err := s.MetaClient.Open(); err != nil {
		return nil, err
	}

	s.TSDBStore = tsdb.NewStore(c.Data.Dir)
	s.TSDBStore.EngineOptions.Config = c.Data

	// Copy TSDB configuration.
	s.TSDBStore.EngineOptions.EngineVersion = c.Data.Engine

	// Create the Subscriber service
	s.Subscriber = subscriber.NewService(c.Subscriber)

	// Initialize points writer.
	s.PointsWriter = cluster.NewPointsWriter()
	s.PointsWriter.WriteTimeout = time.Duration(c.Cluster.WriteTimeout)
	s.PointsWriter.TSDBStore = s.TSDBStore
	s.PointsWriter.Subscriber = s.Subscriber

	// Initialize query executor.
	s.QueryExecutor = cluster.NewQueryExecutor()
	s.QueryExecutor.MetaClient = s.MetaClient
	s.QueryExecutor.TSDBStore = s.TSDBStore
	s.QueryExecutor.Monitor = s.Monitor
	s.QueryExecutor.PointsWriter = s.PointsWriter
	s.QueryExecutor.QueryTimeout = time.Duration(c.Cluster.QueryTimeout)
	s.QueryExecutor.QueryManager = influxql.DefaultQueryManager(c.Cluster.MaxConcurrentQueries)
	s.QueryExecutor.MaxSelectSeriesN = c.Cluster.MaxSelectSeriesN
	if c.Data.QueryLogEnabled {
		s.QueryExecutor.LogOutput = os.Stderr
	}

	// Initialize the monitor
	s.Monitor.Version = s.buildInfo.Version
	s.Monitor.Commit = s.buildInfo.Commit
	s.Monitor.Branch = s.buildInfo.Branch
	s.Monitor.BuildTime = s.buildInfo.Time
	s.Monitor.PointsWriter = (*monitorPointsWriter)(s.PointsWriter)

	return s, nil
}