...

Source file src/scheduler/config/configuration.go

Documentation: scheduler/config

     1  /*
     2   * P2PFaaS - A framework for FaaS Load Balancing
     3   * Copyright (c) 2019 - 2022. Gabriele Proietti Mattia <pm.gabriele@outlook.com>
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17   */
    18  
    19  package config
    20  
    21  import (
    22  	"encoding/json"
    23  	"os"
    24  	"scheduler/log"
    25  	"strconv"
    26  	"strings"
    27  )
    28  
    29  type ConfigError struct{}
    30  
    31  func (ConfigError) Error() string {
    32  	return "Configuration Error"
    33  }
    34  
    35  type ConfigurationStatic struct {
    36  	listeningPort                 uint
    37  	serviceDiscoveryListeningPort uint
    38  	serviceDiscoveryListeningHost string
    39  	serviceLearningListeningPort  uint
    40  	serviceLearningListeningHost  string
    41  	runningEnvironment            string
    42  	profilingEnabled              bool
    43  	dataPath                      string
    44  
    45  	openFaasEnabled       bool
    46  	openFaasListeningPort uint
    47  	openFaasListeningHost string
    48  
    49  	fnList []string
    50  }
    51  
    52  type ConfigurationDynamic struct {
    53  	ParallelRunningFunctionsMax uint `json:"parallel_running_functions_max" bson:"parallel_running_functions_max"`
    54  	QueueLengthMax              uint `json:"queue_length_max" bson:"queue_length_max"`
    55  	QueueEnabled                bool `json:"queue_enabled" bson:"queue_enabled"`
    56  }
    57  
    58  /*
    59   * Getters
    60   */
    61  
    62  func IsConfigurationDynamicReadFromFile() bool {
    63  	return configurationDynamicReadFromFile
    64  }
    65  
    66  func GetRunningFunctionMax() uint {
    67  	return configurationDynamic.ParallelRunningFunctionsMax
    68  }
    69  func GetQueueLengthMax() uint {
    70  	return configurationDynamic.QueueLengthMax
    71  }
    72  func GetQueueEnabled() bool {
    73  	return configurationDynamic.QueueEnabled
    74  }
    75  func GetListeningPort() uint {
    76  	return configurationStatic.listeningPort
    77  }
    78  func GetDataPath() string {
    79  	return configurationStatic.dataPath
    80  }
    81  func GetOpenFaasEnabled() bool {
    82  	return configurationStatic.openFaasEnabled
    83  }
    84  func GetOpenFaasListeningPort() uint {
    85  	return configurationStatic.openFaasListeningPort
    86  }
    87  func GetOpenFaasListeningHost() string {
    88  	return configurationStatic.openFaasListeningHost
    89  }
    90  func GetServiceDiscoveryListeningPort() uint {
    91  	return configurationStatic.serviceDiscoveryListeningPort
    92  }
    93  func GetServiceDiscoveryListeningHost() string {
    94  	return configurationStatic.serviceDiscoveryListeningHost
    95  }
    96  func GetServiceLearningListeningPort() uint {
    97  	return configurationStatic.serviceLearningListeningPort
    98  }
    99  func GetServiceLearningListeningHost() string {
   100  	return configurationStatic.serviceLearningListeningHost
   101  }
   102  func GetRunningEnvironment() string {
   103  	return configurationStatic.runningEnvironment
   104  }
   105  func IsRunningEnvironmentDevelopment() bool {
   106  	// if not already initialized
   107  	if configurationStatic == nil {
   108  		return true
   109  	}
   110  	return configurationStatic.runningEnvironment == RunningEnvironmentDevelopment
   111  }
   112  
   113  // GetFunctionsList is currently unused!
   114  func GetFunctionsList() []string {
   115  	return configurationStatic.fnList
   116  }
   117  
   118  func GetConfigurationDynamicCopy() *ConfigurationDynamic {
   119  	copiedConf := *configurationDynamic
   120  
   121  	return &copiedConf
   122  }
   123  
   124  /*
   125   * Setters
   126   */
   127  
   128  func SetRunningFunctionMax(n uint) {
   129  	configurationDynamic.ParallelRunningFunctionsMax = n
   130  }
   131  func SetQueueLengthMax(n uint) {
   132  	configurationDynamic.QueueLengthMax = n
   133  }
   134  func SetQueueEnabled(b bool) {
   135  	configurationDynamic.QueueEnabled = b
   136  }
   137  
   138  /*
   139   * Inits
   140   */
   141  
   142  // InitConfigurationStatic prepares and inits the static configuration by loading it from env vars.
   143  func InitConfigurationStatic() {
   144  	configurationStatic = GetDefaultConfigurationStatic()
   145  
   146  	if envVar := os.Getenv(EnvRunningEnvironment); envVar != "" {
   147  		if envVar == RunningEnvironmentProduction || envVar == RunningEnvironmentDevelopment {
   148  			configurationStatic.runningEnvironment = envVar
   149  		}
   150  	}
   151  
   152  	if envVar := os.Getenv(EnvServiceDiscoveryListeningHost); envVar != "" {
   153  		configurationStatic.serviceDiscoveryListeningHost = envVar
   154  	}
   155  
   156  	if envVar := os.Getenv(EnvServiceDiscoveryListeningPort); envVar != "" {
   157  		listPort, err := strconv.Atoi(envVar)
   158  		if err == nil && listPort > 0 {
   159  			configurationStatic.serviceDiscoveryListeningPort = uint(listPort)
   160  		}
   161  	}
   162  
   163  	if envVar := os.Getenv(EnvDataPath); envVar != "" {
   164  		configurationStatic.dataPath = envVar
   165  	}
   166  
   167  	if envVar := os.Getenv(EnvServiceLearningListeningHost); envVar != "" {
   168  		configurationStatic.serviceLearningListeningHost = envVar
   169  	}
   170  
   171  	if envVar := os.Getenv(EnvServiceLearningListeningPort); envVar != "" {
   172  		listPort, err := strconv.Atoi(envVar)
   173  		if err == nil && listPort > 0 {
   174  			configurationStatic.serviceLearningListeningPort = uint(listPort)
   175  		}
   176  	}
   177  
   178  	if envVar := os.Getenv(EnvOpenFaasEnabled); envVar != "" {
   179  		enabled, err := strconv.ParseBool(envVar)
   180  		if err == nil {
   181  			configurationStatic.openFaasEnabled = enabled
   182  		}
   183  	}
   184  
   185  	if envVar := os.Getenv(EnvOpenFaasListeningHost); envVar != "" {
   186  		configurationStatic.openFaasListeningHost = envVar
   187  	}
   188  
   189  	if envVar := os.Getenv(EnvOpenFaasListeningPort); envVar != "" {
   190  		listPort, err := strconv.Atoi(envVar)
   191  		if err == nil && listPort > 0 {
   192  			configurationStatic.openFaasListeningPort = uint(listPort)
   193  		}
   194  	}
   195  
   196  	if envVar := os.Getenv(EnvFunctionsList); envVar != "" {
   197  		configurationStatic.fnList = strings.Split(envVar, ",")
   198  	}
   199  
   200  	if envVar := os.Getenv(EnvProfiling); envVar != "" {
   201  		enabled, err := strconv.ParseBool(envVar)
   202  		if err == nil {
   203  			configurationStatic.profilingEnabled = enabled
   204  		}
   205  	}
   206  
   207  }
   208  
   209  // InitConfigurationDynamic prepare the configuration object, returns if config is read from file
   210  func InitConfigurationDynamic() {
   211  	configurationDynamic = GetDefaultConfigurationDynamic()
   212  
   213  	// try to read the dynamic from file
   214  	newConf, err := ReadConfigurationDynamicFromFile()
   215  	if err == nil {
   216  		configurationDynamic = newConf
   217  		configurationDynamicReadFromFile = true
   218  	}
   219  }
   220  
   221  /*
   222   * Utils
   223   */
   224  
   225  // ReadConfigurationDynamicFromFile reads the configuration from a file
   226  func ReadConfigurationDynamicFromFile() (*ConfigurationDynamic, error) {
   227  	conf := GetDefaultConfigurationDynamic()
   228  
   229  	file, err := os.ReadFile(GetConfigFilePath())
   230  	if IsRunningEnvironmentDevelopment() {
   231  		log.Log.Debugf("Read config file=%s", string(file))
   232  	}
   233  	if err != nil {
   234  		log.Log.Warning("Cannot read configuration file at %s", GetConfigFilePath())
   235  	} else {
   236  		err = json.Unmarshal(file, &conf)
   237  		if err != nil {
   238  			log.Log.Errorf("Cannot decode configuration file, maybe not valid json: %s", err.Error())
   239  			return nil, err
   240  		}
   241  	}
   242  
   243  	return conf, nil
   244  }
   245  
   246  // GetDefaultConfigurationDynamic returns the dynamic configuration object with default values
   247  func GetDefaultConfigurationDynamic() *ConfigurationDynamic {
   248  	return &ConfigurationDynamic{
   249  		ParallelRunningFunctionsMax: 4,
   250  		QueueLengthMax:              4, // put always > 0
   251  		QueueEnabled:                true,
   252  	}
   253  }
   254  
   255  // GetDefaultConfigurationStatic returns the static configuration object with default values
   256  func GetDefaultConfigurationStatic() *ConfigurationStatic {
   257  	return &ConfigurationStatic{
   258  		listeningPort:                 DefaultListeningPort,
   259  		serviceDiscoveryListeningPort: DefaultServiceDiscoveryListeningPort,
   260  		serviceDiscoveryListeningHost: DefaultServiceDiscoveryListeningHost,
   261  		serviceLearningListeningPort:  DefaultServiceLearningListeningPort,
   262  		serviceLearningListeningHost:  DefaultServiceLearningListeningHost,
   263  		dataPath:                      DefaultDataPath,
   264  		runningEnvironment:            DefaultRunningEnvironment,
   265  		openFaasEnabled:               false,
   266  		openFaasListeningPort:         DefaultOpenFaaSListeningPort,
   267  		openFaasListeningHost:         DefaultOpenFaaSListeningHost,
   268  		fnList:                        []string{},
   269  		profilingEnabled:              false,
   270  	}
   271  }
   272  

View as plain text