// 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 }
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 }
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 } }
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 } }
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 } }
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 } }
// 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 }