github.com/go-graphite/carbonapi@v0.17.0/expr/metadata/metadata.go (about)

     1  package metadata
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/go-graphite/carbonapi/expr/interfaces"
     7  	"github.com/go-graphite/carbonapi/expr/types"
     8  	"github.com/lomik/zapwriter"
     9  	"go.uber.org/zap"
    10  )
    11  
    12  // RegisterRewriteFunctionWithFilename registers function for a rewrite phase in metadata and fills out all Description structs
    13  func RegisterRewriteFunctionWithFilename(name, filename string, function interfaces.RewriteFunction) {
    14  	FunctionMD.Lock()
    15  	defer FunctionMD.Unlock()
    16  
    17  	if _, ok := FunctionMD.RewriteFunctions[name]; ok {
    18  		n := FunctionMD.RewriteFunctionsFilenames[name]
    19  		logger := zapwriter.Logger("registerRewriteFunction")
    20  		logger.Warn("function already registered, will register new anyway",
    21  			zap.String("name", name),
    22  			zap.String("current_filename", filename),
    23  			zap.Strings("previous_filenames", n),
    24  			zap.Stack("stack"),
    25  		)
    26  	} else {
    27  		FunctionMD.RewriteFunctionsFilenames[name] = make([]string, 0)
    28  	}
    29  	// Check if we are colliding with non-rewrite Functions
    30  	if _, ok := FunctionMD.Functions[name]; ok {
    31  		n := FunctionMD.FunctionsFilenames[name]
    32  		logger := zapwriter.Logger("registerRewriteFunction")
    33  		logger.Warn("non-rewrite function with the same name already registered",
    34  			zap.String("name", name),
    35  			zap.String("current_filename", filename),
    36  			zap.Strings("previous_filenames", n),
    37  			zap.Stack("stack"),
    38  		)
    39  	}
    40  	FunctionMD.RewriteFunctionsFilenames[name] = append(FunctionMD.RewriteFunctionsFilenames[name], filename)
    41  	FunctionMD.RewriteFunctions[name] = function
    42  
    43  	for k, v := range function.Description() {
    44  		FunctionMD.Descriptions[k] = v
    45  		if _, ok := FunctionMD.DescriptionsGrouped[v.Group]; !ok {
    46  			FunctionMD.DescriptionsGrouped[v.Group] = make(map[string]types.FunctionDescription)
    47  		}
    48  		FunctionMD.DescriptionsGrouped[v.Group][k] = v
    49  	}
    50  }
    51  
    52  // RegisterRewriteFunction registers function for a rewrite phase in metadata and fills out all Description structs
    53  func RegisterRewriteFunction(name string, function interfaces.RewriteFunction) {
    54  	RegisterRewriteFunctionWithFilename(name, "", function)
    55  }
    56  
    57  // RegisterFunctionWithFilename registers function in metadata and fills out all Description structs
    58  func RegisterFunctionWithFilename(name, filename string, function interfaces.Function) {
    59  	FunctionMD.Lock()
    60  	defer FunctionMD.Unlock()
    61  
    62  	if _, ok := FunctionMD.Functions[name]; ok {
    63  		n := FunctionMD.FunctionsFilenames[name]
    64  		logger := zapwriter.Logger("registerFunction")
    65  		logger.Warn("function already registered, will register new anyway",
    66  			zap.String("name", name),
    67  			zap.String("current_filename", filename),
    68  			zap.Strings("previous_filenames", n),
    69  			zap.Stack("stack"),
    70  		)
    71  	} else {
    72  		FunctionMD.FunctionsFilenames[name] = make([]string, 0)
    73  	}
    74  	// Check if we are colliding with non-rewrite Functions
    75  	if _, ok := FunctionMD.RewriteFunctions[name]; ok {
    76  		n := FunctionMD.RewriteFunctionsFilenames[name]
    77  		logger := zapwriter.Logger("registerRewriteFunction")
    78  		logger.Warn("rewrite function with the same name already registered",
    79  			zap.String("name", name),
    80  			zap.String("current_filename", filename),
    81  			zap.Strings("previous_filenames", n),
    82  			zap.Stack("stack"),
    83  		)
    84  	}
    85  	FunctionMD.Functions[name] = function
    86  	FunctionMD.FunctionsFilenames[name] = append(FunctionMD.FunctionsFilenames[name], filename)
    87  
    88  	for k, v := range function.Description() {
    89  		FunctionMD.Descriptions[k] = v
    90  		if _, ok := FunctionMD.DescriptionsGrouped[v.Group]; !ok {
    91  			FunctionMD.DescriptionsGrouped[v.Group] = make(map[string]types.FunctionDescription)
    92  		}
    93  		FunctionMD.DescriptionsGrouped[v.Group][k] = v
    94  	}
    95  }
    96  
    97  // RegisterFunction registers function in metadata and fills out all Description structs
    98  func RegisterFunction(name string, function interfaces.Function) {
    99  	RegisterFunctionWithFilename(name, "", function)
   100  }
   101  
   102  // Metadata is a type to store global function metadata
   103  type Metadata struct {
   104  	sync.RWMutex
   105  
   106  	Functions                 map[string]interfaces.Function
   107  	RewriteFunctions          map[string]interfaces.RewriteFunction
   108  	Descriptions              map[string]types.FunctionDescription
   109  	DescriptionsGrouped       map[string]map[string]types.FunctionDescription
   110  	FunctionConfigFiles       map[string]string
   111  	FunctionsFilenames        map[string][]string
   112  	RewriteFunctionsFilenames map[string][]string
   113  
   114  	evaluator interfaces.Evaluator
   115  }
   116  
   117  // FunctionMD is actual global variable that stores metadata
   118  var FunctionMD = Metadata{
   119  	RewriteFunctions:          make(map[string]interfaces.RewriteFunction),
   120  	Functions:                 make(map[string]interfaces.Function),
   121  	Descriptions:              make(map[string]types.FunctionDescription),
   122  	DescriptionsGrouped:       make(map[string]map[string]types.FunctionDescription),
   123  	FunctionConfigFiles:       make(map[string]string),
   124  	FunctionsFilenames:        make(map[string][]string),
   125  	RewriteFunctionsFilenames: make(map[string][]string),
   126  }