Skip to content

Commit

Permalink
chore: fix lint
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangnv-bkhn committed Jan 3, 2025
1 parent 870c7f8 commit b8da3e1
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 64 deletions.
3 changes: 2 additions & 1 deletion examples/data_export_log_and_file/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ func main() {
- Main exporter will generate 4 files containing 3, 2, 2, 1 events respectively
- Secondary exporter will generate 3 files containing 5, 2, 1 events respectively
- Tertiary exporter will generate 3 files containing 4, 3, 1 events respectively
- Logger will generate 8 logs
- Logger will generate 8 events in the logs
(format "IMMEDIATE - user=\"{{ .UserKey}}\", flag=\"{{ .Key}}\", value=\"{{ .Value}}\", variation=\"{{ .Variation}}\"")
*/
}
145 changes: 82 additions & 63 deletions feature_flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,18 @@ type GoFeatureFlag struct {
var ff *GoFeatureFlag
var onceFF sync.Once

// New creates a new go-feature-flag instances that retrieve the config from a YAML file
// and return everything you need to manage your flags.
func New(config Config) (*GoFeatureFlag, error) {
// validateAndSetDefaults validates the config and sets default values
func validateAndSetDefaults(config *Config) error {
switch {
case config.PollingInterval == 0:
// The default value for the poll interval is 60 seconds
config.PollingInterval = 60 * time.Second
case config.PollingInterval < 0:
// Check that value is not negative
return nil, fmt.Errorf("%d is not a valid PollingInterval value, it need to be > 0", config.PollingInterval)
return fmt.Errorf("%d is not a valid PollingInterval value, it need to be > 0", config.PollingInterval)
case config.PollingInterval < time.Second:
// the minimum value for the polling policy is 1 second
config.PollingInterval = time.Second
default:
// do nothing
}

if config.offlineMutex == nil {
Expand All @@ -80,6 +77,75 @@ func New(config Config) (*GoFeatureFlag, error) {
LegacyLogger: config.Logger,
}

return nil
}

// initializeRetrievers sets up and initializes the retriever manager
func initializeRetrievers(config Config) (*retriever.Manager, error) {
retrievers, err := config.GetRetrievers()
if err != nil {
return nil, err
}

manager := retriever.NewManager(config.Context, retrievers, config.internalLogger)
err = manager.Init(config.Context)
if err != nil && !config.StartWithRetrieverError {
return nil, fmt.Errorf("impossible to initialize the retrievers, please check your configuration: %v", err)
}

Check warning on line 94 in feature_flag.go

View check run for this annotation

Codecov / codecov/patch

feature_flag.go#L93-L94

Added lines #L93 - L94 were not covered by tests

return manager, nil
}

// initializeExporters sets up the data exporters and starts their daemons if needed
func initializeExporters(config Config) ([]*exporter.Scheduler, error) {

Check failure on line 100 in feature_flag.go

View workflow job for this annotation

GitHub Actions / Lint

initializeExporters - result 1 (error) is always nil (unparam)
dataExporters := config.GetDataExporters()
if len(dataExporters) == 0 {
return nil, nil
}

var scheduler *exporter.Scheduler
if len(dataExporters) == 1 {
scheduler = exporter.NewScheduler(
config.Context,
dataExporters[0].FlushInterval,
dataExporters[0].MaxEventInMemory,
dataExporters[0].Exporter,
config.internalLogger,
)
} else {
exporterConfigs := make([]exporter.Config, len(dataExporters))
for i, de := range dataExporters {
exporterConfigs[i] = exporter.Config{
Exporter: de.Exporter,
FlushInterval: de.FlushInterval,
MaxEventInMemory: de.MaxEventInMemory,
}
}
scheduler = exporter.NewMultiScheduler(
config.Context,
exporterConfigs,
config.internalLogger,
)

Check warning on line 128 in feature_flag.go

View check run for this annotation

Codecov / codecov/patch

feature_flag.go#L116-L128

Added lines #L116 - L128 were not covered by tests
}

// Start daemon if we have any bulk exporters
for _, de := range dataExporters {
if de.Exporter.IsBulk() {
go scheduler.StartDaemon()
break
}
}

return []*exporter.Scheduler{scheduler}, nil
}

// New creates a new go-feature-flag instances that retrieve the config from a YAML file
// and return everything you need to manage your flags.
func New(config Config) (*GoFeatureFlag, error) {
if err := validateAndSetDefaults(&config); err != nil {
return nil, err
}

goFF := &GoFeatureFlag{
config: config,
}
Expand All @@ -92,28 +158,23 @@ func New(config Config) (*GoFeatureFlag, error) {
goFF.bgUpdater = newBackgroundUpdater(config.PollingInterval, config.EnablePollingJitter)
goFF.cache = cache.New(notificationService, config.PersistentFlagConfigurationFile, config.internalLogger)

retrievers, err := config.GetRetrievers()
retrieverManager, err := initializeRetrievers(config)
if err != nil {
return nil, err
}
goFF.retrieverManager = retriever.NewManager(config.Context, retrievers, config.internalLogger)
err = goFF.retrieverManager.Init(config.Context)
if err != nil && !config.StartWithRetrieverError {
return nil, fmt.Errorf("impossible to initialize the retrievers, please check your configuration: %v", err)
}
goFF.retrieverManager = retrieverManager

err = retrieveFlagsAndUpdateCache(goFF.config, goFF.cache, goFF.retrieverManager, true)
if err != nil {
switch {
case config.PersistentFlagConfigurationFile != "":
if config.PersistentFlagConfigurationFile != "" {

Check failure on line 169 in feature_flag.go

View workflow job for this annotation

GitHub Actions / Lint

ifElseChain: rewrite if-else to switch statement (gocritic)
errPersist := retrievePersistentLocalDisk(config.Context, config, goFF)
if errPersist != nil && !config.StartWithRetrieverError {
return nil, fmt.Errorf("impossible to use the persistent flag configuration file: %v "+
"[original error: %v]", errPersist, err)
}
case !config.StartWithRetrieverError:
} else if !config.StartWithRetrieverError {
return nil, fmt.Errorf("impossible to retrieve the flags, please check your configuration: %v", err)
default:
} else {
// We accept to start with a retriever error, we will serve only default value
goFF.config.internalLogger.Error("Impossible to retrieve the flags, starting with the "+
"retriever error", slog.Any("error", err))
Expand All @@ -122,55 +183,13 @@ func New(config Config) (*GoFeatureFlag, error) {

go goFF.startFlagUpdaterDaemon()

dataExporters := config.GetDataExporters()

// Initialize a Scheduler for each DataExporter, if any DataExporter is configured.
if len(dataExporters) > 0 {
var scheduler *exporter.Scheduler
if len(dataExporters) == 1 {
// Single exporter case
scheduler = exporter.NewScheduler(
goFF.config.Context,
dataExporters[0].FlushInterval,
dataExporters[0].MaxEventInMemory,
dataExporters[0].Exporter,
goFF.config.internalLogger,
)
} else {
// Multiple exporters case
exporterConfigs := make([]exporter.Config, len(dataExporters))
for i, de := range dataExporters {
exporterConfigs[i] = exporter.Config{
Exporter: de.Exporter,
FlushInterval: de.FlushInterval,
MaxEventInMemory: de.MaxEventInMemory,
}
}

scheduler = exporter.NewMultiScheduler(
goFF.config.Context,
exporterConfigs,
goFF.config.internalLogger,
)
}

// Start daemon if we have any bulk exporters
hasBulkExporters := false
for _, de := range dataExporters {
if de.Exporter.IsBulk() {
hasBulkExporters = true
break
}
}
if hasBulkExporters {
go scheduler.StartDaemon()
}

// Store the scheduler
goFF.dataExporterSchedulers = make([]*exporter.Scheduler, 1)
goFF.dataExporterSchedulers[0] = scheduler
schedulers, err := initializeExporters(config)
if err != nil {
return nil, err

Check warning on line 188 in feature_flag.go

View check run for this annotation

Codecov / codecov/patch

feature_flag.go#L188

Added line #L188 was not covered by tests
}
goFF.dataExporterSchedulers = schedulers
}

config.internalLogger.Debug("GO Feature Flag is initialized")
return goFF, nil
}
Expand Down

0 comments on commit b8da3e1

Please sign in to comment.