package pubsubmon import ( "encoding/json" "errors" "time" "github.com/ipfs/ipfs-cluster/config" "github.com/kelseyhightower/envconfig" ) const configKey = "pubsubmon" const envConfigKey = "cluster_pubsubmon" // Default values for this Config. const ( DefaultCheckInterval = 15 * time.Second DefaultFailureThreshold = 3.0 ) // Config allows to initialize a Monitor and customize some parameters. type Config struct { config.Saver CheckInterval time.Duration // FailureThreshold indicates when a peer should be considered failed. // The greater the threshold value the more leniency is granted. // A value between 2.0 and 4.0 is suggested for the threshold. FailureThreshold float64 } type jsonConfig struct { CheckInterval string `json:"check_interval"` FailureThreshold *float64 `json:"failure_threshold"` } // ConfigKey provides a human-friendly identifier for this type of Config. func (cfg *Config) ConfigKey() string { return configKey } // Default sets the fields of this Config to sensible values. func (cfg *Config) Default() error { cfg.CheckInterval = DefaultCheckInterval cfg.FailureThreshold = DefaultFailureThreshold return nil } // ApplyEnvVars fills in any Config fields found // as environment variables. func (cfg *Config) ApplyEnvVars() error { jcfg := cfg.toJSONConfig() err := envconfig.Process(envConfigKey, jcfg) if err != nil { return err } return cfg.applyJSONConfig(jcfg) } // Validate checks that the fields of this Config have working values, // at least in appearance. func (cfg *Config) Validate() error { if cfg.CheckInterval <= 0 { return errors.New("pubsubmon.check_interval too low") } if cfg.FailureThreshold <= 0 { return errors.New("pubsubmon.failure_threshold too low") } return nil } // LoadJSON sets the fields of this Config to the values defined by the JSON // representation of it, as generated by ToJSON. func (cfg *Config) LoadJSON(raw []byte) error { jcfg := &jsonConfig{} err := json.Unmarshal(raw, jcfg) if err != nil { logger.Error("Error unmarshaling pubsubmon monitor config") return err } cfg.Default() return cfg.applyJSONConfig(jcfg) } func (cfg *Config) applyJSONConfig(jcfg *jsonConfig) error { interval, _ := time.ParseDuration(jcfg.CheckInterval) cfg.CheckInterval = interval if jcfg.FailureThreshold != nil { cfg.FailureThreshold = *jcfg.FailureThreshold } return cfg.Validate() } // ToJSON generates a human-friendly JSON representation of this Config. func (cfg *Config) ToJSON() ([]byte, error) { jcfg := cfg.toJSONConfig() return json.MarshalIndent(jcfg, "", " ") } func (cfg *Config) toJSONConfig() *jsonConfig { return &jsonConfig{ CheckInterval: cfg.CheckInterval.String(), FailureThreshold: &cfg.FailureThreshold, } }