示例#1
0
// iteratorCreator returns a new instance of IteratorCreator based on stmt.
func (e *QueryExecutor) iteratorCreator(stmt *influxql.SelectStatement, opt *influxql.SelectOptions) (influxql.IteratorCreator, error) {
	// Retrieve a list of shard IDs.
	shards, err := e.MetaClient.ShardsByTimeRange(stmt.Sources, opt.MinTime, opt.MaxTime)
	if err != nil {
		return nil, err
	}

	// Generate iterators for each node.
	ics := make([]influxql.IteratorCreator, 0)
	if err := func() error {
		for _, shard := range shards {
			ic := e.TSDBStore.ShardIteratorCreator(shard.ID)
			if ic == nil {
				continue
			}
			ics = append(ics, ic)
		}

		return nil
	}(); err != nil {
		influxql.IteratorCreators(ics).Close()
		return nil, err
	}

	return influxql.IteratorCreators(ics), nil
}
示例#2
0
func (s *Store) IteratorCreator(shards []uint64) (influxql.IteratorCreator, error) {
	// Generate iterators for each node.
	ics := make([]influxql.IteratorCreator, 0)
	if err := func() error {
		for _, id := range shards {
			ic := s.ShardIteratorCreator(id)
			if ic == nil {
				continue
			}
			ics = append(ics, ic)
		}

		return nil
	}(); err != nil {
		influxql.IteratorCreators(ics).Close()
		return nil, err
	}

	return influxql.IteratorCreators(ics), nil
}
func (s *TSDBStore) IteratorCreator(shards []meta.ShardInfo, opt *influxql.SelectOptions) (influxql.IteratorCreator, error) {
	// Generate iterators for each node.
	ics := make([]influxql.IteratorCreator, 0)
	if err := func() error {
		for _, shard := range shards {
			ic := s.ShardIteratorCreator(shard.ID)
			if ic == nil {
				continue
			}
			ics = append(ics, ic)
		}

		return nil
	}(); err != nil {
		influxql.IteratorCreators(ics).Close()
		return nil, err
	}

	return influxql.IteratorCreators(ics), nil
}
示例#4
0
func (s *Service) processCreateIteratorRequest(conn net.Conn) {
	defer conn.Close()

	var itr influxql.Iterator
	if err := func() error {
		// Parse request.
		var req CreateIteratorRequest
		if err := DecodeLV(conn, &req); err != nil {
			return err
		}

		// Collect iterator creators for each shard.
		ics := make([]influxql.IteratorCreator, 0, len(req.ShardIDs))
		for _, shardID := range req.ShardIDs {
			ic := s.TSDBStore.ShardIteratorCreator(shardID)
			if ic == nil {
				return nil
			}
			ics = append(ics, ic)
		}

		// Generate a single iterator from all shards.
		i, err := influxql.IteratorCreators(ics).CreateIterator(req.Opt)
		if err != nil {
			return err
		}
		itr = i

		return nil
	}(); err != nil {
		itr.Close()
		s.Logger.Printf("error reading CreateIterator request: %s", err)
		EncodeTLV(conn, createIteratorResponseMessage, &CreateIteratorResponse{Err: err})
		return
	}

	// Encode success response.
	if err := EncodeTLV(conn, createIteratorResponseMessage, &CreateIteratorResponse{}); err != nil {
		s.Logger.Printf("error writing CreateIterator response: %s", err)
		return
	}

	// Exit if no iterator was produced.
	if itr == nil {
		return
	}

	// Stream iterator to connection.
	if err := influxql.NewIteratorEncoder(conn).EncodeIterator(itr); err != nil {
		s.Logger.Printf("error encoding CreateIterator iterator: %s", err)
		return
	}
}
示例#5
0
func (s *Service) processFieldDimensionsRequest(conn net.Conn) {
	var fields, dimensions map[string]struct{}
	if err := func() error {
		// Parse request.
		var req FieldDimensionsRequest
		if err := DecodeLV(conn, &req); err != nil {
			return err
		}

		sh, ok := s.TSDBStore.(ShardIteratorCreator)
		if !ok {
			return errors.New("unable to access a specific shard with this tsdb store")
		}

		// Collect iterator creators for each shard.
		ics := make([]influxql.IteratorCreator, 0, len(req.ShardIDs))
		for _, shardID := range req.ShardIDs {
			ic := sh.ShardIteratorCreator(shardID)
			if ic == nil {
				return nil
			}
			ics = append(ics, ic)
		}

		// Generate a single iterator from all shards.
		f, d, err := influxql.IteratorCreators(ics).FieldDimensions(req.Sources)
		if err != nil {
			return err
		}
		fields, dimensions = f, d

		return nil
	}(); err != nil {
		s.Logger.Printf("error reading FieldDimensions request: %s", err)
		EncodeTLV(conn, fieldDimensionsResponseMessage, &FieldDimensionsResponse{Err: err})
		return
	}

	// Encode success response.
	if err := EncodeTLV(conn, fieldDimensionsResponseMessage, &FieldDimensionsResponse{
		Fields:     fields,
		Dimensions: dimensions,
	}); err != nil {
		s.Logger.Printf("error writing FieldDimensions response: %s", err)
		return
	}
}
示例#6
0
func (s *Service) processSeriesKeysRequest(conn net.Conn) {
	var seriesList influxql.SeriesList
	if err := func() error {
		// Parse request.
		var req SeriesKeysRequest
		if err := DecodeLV(conn, &req); err != nil {
			return err
		}

		sh, ok := s.TSDBStore.(ShardIteratorCreator)
		if !ok {
			return errors.New("unable to access a specific shard with this tsdb store")
		}

		// Collect iterator creators for each shard.
		ics := make([]influxql.IteratorCreator, 0, len(req.ShardIDs))
		for _, shardID := range req.ShardIDs {
			ic := sh.ShardIteratorCreator(shardID)
			if ic == nil {
				return nil
			}
			ics = append(ics, ic)
		}

		// Generate a single iterator from all shards.
		a, err := influxql.IteratorCreators(ics).SeriesKeys(req.Opt)
		if err != nil {
			return err
		}
		seriesList = a

		return nil
	}(); err != nil {
		s.Logger.Printf("error reading SeriesKeys request: %s", err)
		EncodeTLV(conn, seriesKeysResponseMessage, &SeriesKeysResponse{Err: err})
		return
	}

	// Encode success response.
	if err := EncodeTLV(conn, seriesKeysResponseMessage, &SeriesKeysResponse{
		SeriesList: seriesList,
	}); err != nil {
		s.Logger.Printf("error writing SeriesKeys response: %s", err)
		return
	}
}
示例#7
0
func (s *Service) processCreateIteratorRequest(conn net.Conn) {
	defer conn.Close()

	var itr influxql.Iterator
	if err := func() error {
		// Parse request.
		var req CreateIteratorRequest
		if err := DecodeLV(conn, &req); err != nil {
			return err
		}

		sh, ok := s.TSDBStore.(ShardIteratorCreator)
		if !ok {
			return errors.New("unable to access a specific shard with this tsdb store")
		}

		// Collect iterator creators for each shard.
		ics := make([]influxql.IteratorCreator, 0, len(req.ShardIDs))
		for _, shardID := range req.ShardIDs {
			ic := sh.ShardIteratorCreator(shardID)
			if ic == nil {
				continue
			}
			ics = append(ics, ic)
		}

		// Return immediately if there are no iterator creators.
		if len(ics) == 0 {
			return nil
		}

		// Generate a single iterator from all shards.
		i, err := influxql.IteratorCreators(ics).CreateIterator(req.Opt)
		if err != nil {
			return err
		}
		itr = i

		return nil
	}(); err != nil {
		s.Logger.Printf("error reading CreateIterator request: %s", err)
		EncodeTLV(conn, createIteratorResponseMessage, &CreateIteratorResponse{Err: err})
		return
	}

	resp := CreateIteratorResponse{}
	if itr != nil {
		switch itr.(type) {
		case influxql.FloatIterator:
			resp.Type = influxql.Float
		case influxql.IntegerIterator:
			resp.Type = influxql.Integer
		case influxql.StringIterator:
			resp.Type = influxql.String
		case influxql.BooleanIterator:
			resp.Type = influxql.Boolean
		}
		resp.Stats = itr.Stats()
	}

	// Encode success response.
	if err := EncodeTLV(conn, createIteratorResponseMessage, &resp); err != nil {
		s.Logger.Printf("error writing CreateIterator response: %s", err)
		return
	}

	// Exit if no iterator was produced.
	if itr == nil {
		return
	}

	// Stream iterator to connection.
	if err := influxql.NewIteratorEncoder(conn).EncodeIterator(itr); err != nil {
		s.Logger.Printf("error encoding CreateIterator iterator: %s", err)
		return
	}
}
示例#8
0
// iteratorCreator returns a new instance of IteratorCreator based on stmt.
func (e *QueryExecutor) iteratorCreator(stmt *influxql.SelectStatement, opt *influxql.SelectOptions) (influxql.IteratorCreator, error) {
	// Retrieve a list of shard IDs.
	shards, err := e.MetaClient.ShardsByTimeRange(stmt.Sources, opt.MinTime, opt.MaxTime)
	if err != nil {
		return nil, err
	}

	// Map shards to nodes.
	shardIDsByNodeID := make(map[uint64][]uint64)
	for _, si := range shards {
		// Always assign to local node if it has the shard.
		// Otherwise randomly select a remote node.
		var nodeID uint64
		if si.OwnedBy(e.Node.ID) {
			nodeID = e.Node.ID
		} else if len(si.Owners) > 0 {
			nodeID = si.Owners[rand.Intn(len(si.Owners))].NodeID
		} else {
			// This should not occur but if the shard has no owners then
			// we don't want this to panic by trying to randomly select a node.
			continue
		}

		// Otherwise assign it to a remote shard randomly.
		shardIDsByNodeID[nodeID] = append(shardIDsByNodeID[nodeID], si.ID)
	}

	// Generate iterators for each node.
	ics := make([]influxql.IteratorCreator, 0)
	if err := func() error {
		for nodeID, shardIDs := range shardIDsByNodeID {
			// Sort shard IDs so we get more predicable execution.
			sort.Sort(uint64Slice(shardIDs))

			// Create iterator creators from TSDB if local.
			if nodeID == e.Node.ID {
				for _, shardID := range shardIDs {
					ic := e.TSDBStore.ShardIteratorCreator(shardID)
					if ic == nil {
						continue
					}
					ics = append(ics, ic)
				}
				continue
			}

			// Otherwise create iterator creator remotely.
			dialer := &NodeDialer{
				MetaClient: e.MetaClient,
				Timeout:    e.Timeout,
			}
			ics = append(ics, newRemoteIteratorCreator(dialer, nodeID, shardIDs))
		}

		return nil
	}(); err != nil {
		influxql.IteratorCreators(ics).Close()
		return nil, err
	}

	return influxql.IteratorCreators(ics), nil
}