@@ -54,21 +54,18 @@ type GoFeatureFlag struct {
54
54
var ff * GoFeatureFlag
55
55
var onceFF sync.Once
56
56
57
- // New creates a new go-feature-flag instances that retrieve the config from a YAML file
58
- // and return everything you need to manage your flags.
59
- func New (config Config ) (* GoFeatureFlag , error ) {
57
+ // validateAndSetDefaults validates the config and sets default values
58
+ func validateAndSetDefaults (config * Config ) error {
60
59
switch {
61
60
case config .PollingInterval == 0 :
62
61
// The default value for the poll interval is 60 seconds
63
62
config .PollingInterval = 60 * time .Second
64
63
case config .PollingInterval < 0 :
65
64
// Check that value is not negative
66
- return nil , fmt .Errorf ("%d is not a valid PollingInterval value, it need to be > 0" , config .PollingInterval )
65
+ return fmt .Errorf ("%d is not a valid PollingInterval value, it need to be > 0" , config .PollingInterval )
67
66
case config .PollingInterval < time .Second :
68
67
// the minimum value for the polling policy is 1 second
69
68
config .PollingInterval = time .Second
70
- default :
71
- // do nothing
72
69
}
73
70
74
71
if config .offlineMutex == nil {
@@ -80,6 +77,75 @@ func New(config Config) (*GoFeatureFlag, error) {
80
77
LegacyLogger : config .Logger ,
81
78
}
82
79
80
+ return nil
81
+ }
82
+
83
+ // initializeRetrievers sets up and initializes the retriever manager
84
+ func initializeRetrievers (config Config ) (* retriever.Manager , error ) {
85
+ retrievers , err := config .GetRetrievers ()
86
+ if err != nil {
87
+ return nil , err
88
+ }
89
+
90
+ manager := retriever .NewManager (config .Context , retrievers , config .internalLogger )
91
+ err = manager .Init (config .Context )
92
+ if err != nil && ! config .StartWithRetrieverError {
93
+ return nil , fmt .Errorf ("impossible to initialize the retrievers, please check your configuration: %v" , err )
94
+ }
95
+
96
+ return manager , nil
97
+ }
98
+
99
+ // initializeExporters sets up the data exporters and starts their daemons if needed
100
+ func initializeExporters (config Config ) ([]* exporter.Scheduler , error ) {
101
+ dataExporters := config .GetDataExporters ()
102
+ if len (dataExporters ) == 0 {
103
+ return nil , nil
104
+ }
105
+
106
+ var scheduler * exporter.Scheduler
107
+ if len (dataExporters ) == 1 {
108
+ scheduler = exporter .NewScheduler (
109
+ config .Context ,
110
+ dataExporters [0 ].FlushInterval ,
111
+ dataExporters [0 ].MaxEventInMemory ,
112
+ dataExporters [0 ].Exporter ,
113
+ config .internalLogger ,
114
+ )
115
+ } else {
116
+ exporterConfigs := make ([]exporter.Config , len (dataExporters ))
117
+ for i , de := range dataExporters {
118
+ exporterConfigs [i ] = exporter.Config {
119
+ Exporter : de .Exporter ,
120
+ FlushInterval : de .FlushInterval ,
121
+ MaxEventInMemory : de .MaxEventInMemory ,
122
+ }
123
+ }
124
+ scheduler = exporter .NewMultiScheduler (
125
+ config .Context ,
126
+ exporterConfigs ,
127
+ config .internalLogger ,
128
+ )
129
+ }
130
+
131
+ // Start daemon if we have any bulk exporters
132
+ for _ , de := range dataExporters {
133
+ if de .Exporter .IsBulk () {
134
+ go scheduler .StartDaemon ()
135
+ break
136
+ }
137
+ }
138
+
139
+ return []* exporter.Scheduler {scheduler }, nil
140
+ }
141
+
142
+ // New creates a new go-feature-flag instances that retrieve the config from a YAML file
143
+ // and return everything you need to manage your flags.
144
+ func New (config Config ) (* GoFeatureFlag , error ) {
145
+ if err := validateAndSetDefaults (& config ); err != nil {
146
+ return nil , err
147
+ }
148
+
83
149
goFF := & GoFeatureFlag {
84
150
config : config ,
85
151
}
@@ -92,28 +158,23 @@ func New(config Config) (*GoFeatureFlag, error) {
92
158
goFF .bgUpdater = newBackgroundUpdater (config .PollingInterval , config .EnablePollingJitter )
93
159
goFF .cache = cache .New (notificationService , config .PersistentFlagConfigurationFile , config .internalLogger )
94
160
95
- retrievers , err := config . GetRetrievers ( )
161
+ retrieverManager , err := initializeRetrievers ( config )
96
162
if err != nil {
97
163
return nil , err
98
164
}
99
- goFF .retrieverManager = retriever .NewManager (config .Context , retrievers , config .internalLogger )
100
- err = goFF .retrieverManager .Init (config .Context )
101
- if err != nil && ! config .StartWithRetrieverError {
102
- return nil , fmt .Errorf ("impossible to initialize the retrievers, please check your configuration: %v" , err )
103
- }
165
+ goFF .retrieverManager = retrieverManager
104
166
105
167
err = retrieveFlagsAndUpdateCache (goFF .config , goFF .cache , goFF .retrieverManager , true )
106
168
if err != nil {
107
- switch {
108
- case config .PersistentFlagConfigurationFile != "" :
169
+ if config .PersistentFlagConfigurationFile != "" {
109
170
errPersist := retrievePersistentLocalDisk (config .Context , config , goFF )
110
171
if errPersist != nil && ! config .StartWithRetrieverError {
111
172
return nil , fmt .Errorf ("impossible to use the persistent flag configuration file: %v " +
112
173
"[original error: %v]" , errPersist , err )
113
174
}
114
- case ! config .StartWithRetrieverError :
175
+ } else if ! config .StartWithRetrieverError {
115
176
return nil , fmt .Errorf ("impossible to retrieve the flags, please check your configuration: %v" , err )
116
- default :
177
+ } else {
117
178
// We accept to start with a retriever error, we will serve only default value
118
179
goFF .config .internalLogger .Error ("Impossible to retrieve the flags, starting with the " +
119
180
"retriever error" , slog .Any ("error" , err ))
@@ -122,55 +183,13 @@ func New(config Config) (*GoFeatureFlag, error) {
122
183
123
184
go goFF .startFlagUpdaterDaemon ()
124
185
125
- dataExporters := config .GetDataExporters ()
126
-
127
- // Initialize a Scheduler for each DataExporter, if any DataExporter is configured.
128
- if len (dataExporters ) > 0 {
129
- var scheduler * exporter.Scheduler
130
- if len (dataExporters ) == 1 {
131
- // Single exporter case
132
- scheduler = exporter .NewScheduler (
133
- goFF .config .Context ,
134
- dataExporters [0 ].FlushInterval ,
135
- dataExporters [0 ].MaxEventInMemory ,
136
- dataExporters [0 ].Exporter ,
137
- goFF .config .internalLogger ,
138
- )
139
- } else {
140
- // Multiple exporters case
141
- exporterConfigs := make ([]exporter.Config , len (dataExporters ))
142
- for i , de := range dataExporters {
143
- exporterConfigs [i ] = exporter.Config {
144
- Exporter : de .Exporter ,
145
- FlushInterval : de .FlushInterval ,
146
- MaxEventInMemory : de .MaxEventInMemory ,
147
- }
148
- }
149
-
150
- scheduler = exporter .NewMultiScheduler (
151
- goFF .config .Context ,
152
- exporterConfigs ,
153
- goFF .config .internalLogger ,
154
- )
155
- }
156
-
157
- // Start daemon if we have any bulk exporters
158
- hasBulkExporters := false
159
- for _ , de := range dataExporters {
160
- if de .Exporter .IsBulk () {
161
- hasBulkExporters = true
162
- break
163
- }
164
- }
165
- if hasBulkExporters {
166
- go scheduler .StartDaemon ()
167
- }
168
-
169
- // Store the scheduler
170
- goFF .dataExporterSchedulers = make ([]* exporter.Scheduler , 1 )
171
- goFF .dataExporterSchedulers [0 ] = scheduler
186
+ schedulers , err := initializeExporters (config )
187
+ if err != nil {
188
+ return nil , err
172
189
}
190
+ goFF .dataExporterSchedulers = schedulers
173
191
}
192
+
174
193
config .internalLogger .Debug ("GO Feature Flag is initialized" )
175
194
return goFF , nil
176
195
}
0 commit comments