Skip to content

Commit 7d00e46

Browse files
committed
chore: fix lints
1 parent 9f732ca commit 7d00e46

File tree

4 files changed

+92
-73
lines changed

4 files changed

+92
-73
lines changed

examples/data_export_log_and_file/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ func main() {
160160
- Main exporter will generate 4 files containing 3, 2, 2, 1 events respectively
161161
- Secondary exporter will generate 3 files containing 5, 2, 1 events respectively
162162
- Tertiary exporter will generate 3 files containing 4, 3, 1 events respectively
163-
- Logger will generate 8 logs
163+
- Logger will generate 8 events in the logs
164+
(format "IMMEDIATE - user=\"{{ .UserKey}}\", flag=\"{{ .Key}}\", value=\"{{ .Value}}\", variation=\"{{ .Variation}}\"")
164165
*/
165166
}

exporter/data_exporter.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ const (
1717
)
1818

1919
// ExporterConfig holds the configuration for an individual exporter
20-
type ExporterConfig struct {
20+
type Config struct {
2121
Exporter CommonExporter
2222
FlushInterval time.Duration
2323
MaxEventInMemory int64
2424
}
2525

2626
// ExporterState maintains the state for a single exporter
27-
type ExporterState struct {
28-
config ExporterConfig
27+
type State struct {
28+
config Config
2929
ticker *time.Ticker
3030
lastIndex int // Index of the last processed event
3131
}
3232

3333
// Scheduler handles data collection for one or more exporters
3434
type Scheduler struct {
3535
sharedCache []FeatureEvent
36-
bulkExporters map[CommonExporter]*ExporterState // Only bulk exporters that need periodic flushing
37-
directExporters []CommonExporter // Non-bulk exporters that flush immediately
36+
bulkExporters map[CommonExporter]*State // Only bulk exporters that need periodic flushing
37+
directExporters []CommonExporter // Non-bulk exporters that flush immediately
3838
mutex sync.Mutex
3939
daemonChan chan struct{}
4040
logger *fflog.FFLogger
@@ -46,22 +46,22 @@ func NewScheduler(ctx context.Context, flushInterval time.Duration, maxEventInMe
4646
exp CommonExporter, logger *fflog.FFLogger,
4747
) *Scheduler {
4848
// Convert single exporter parameters to ExporterConfig
49-
config := ExporterConfig{
49+
config := Config{
5050
Exporter: exp,
5151
FlushInterval: flushInterval,
5252
MaxEventInMemory: maxEventInMemory,
5353
}
54-
return NewMultiScheduler(ctx, []ExporterConfig{config}, logger)
54+
return NewMultiScheduler(ctx, []Config{config}, logger)
5555
}
5656

5757
// NewMultiScheduler creates a scheduler that handles multiple exporters
58-
func NewMultiScheduler(ctx context.Context, exporterConfigs []ExporterConfig, logger *fflog.FFLogger,
58+
func NewMultiScheduler(ctx context.Context, exporterConfigs []Config, logger *fflog.FFLogger,
5959
) *Scheduler {
6060
if ctx == nil {
6161
ctx = context.Background()
6262
}
6363

64-
bulkExporters := make(map[CommonExporter]*ExporterState)
64+
bulkExporters := make(map[CommonExporter]*State)
6565
directExporters := make([]CommonExporter, 0)
6666

6767
for _, config := range exporterConfigs {
@@ -73,7 +73,7 @@ func NewMultiScheduler(ctx context.Context, exporterConfigs []ExporterConfig, lo
7373
}
7474

7575
if config.Exporter.IsBulk() {
76-
state := &ExporterState{
76+
state := &State{
7777
config: config,
7878
lastIndex: -1,
7979
ticker: time.NewTicker(config.FlushInterval),
@@ -130,15 +130,15 @@ func (s *Scheduler) AddEvent(event FeatureEvent) {
130130
}
131131

132132
// getPendingEvents returns events that haven't been processed by this exporter
133-
func (s *Scheduler) getPendingEvents(state *ExporterState) []FeatureEvent {
133+
func (s *Scheduler) getPendingEvents(state *State) []FeatureEvent {
134134
if state.lastIndex+1 >= len(s.sharedCache) {
135135
return nil
136136
}
137137
return s.sharedCache[state.lastIndex+1:]
138138
}
139139

140140
// flushExporter sends pending events to the specified exporter
141-
func (s *Scheduler) flushExporter(state *ExporterState) {
141+
func (s *Scheduler) flushExporter(state *State) {
142142
pendingEvents := s.getPendingEvents(state)
143143
if len(pendingEvents) == 0 {
144144
return

feature_flag.go

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,18 @@ type GoFeatureFlag struct {
5454
var ff *GoFeatureFlag
5555
var onceFF sync.Once
5656

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 {
6059
switch {
6160
case config.PollingInterval == 0:
6261
// The default value for the poll interval is 60 seconds
6362
config.PollingInterval = 60 * time.Second
6463
case config.PollingInterval < 0:
6564
// 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)
6766
case config.PollingInterval < time.Second:
6867
// the minimum value for the polling policy is 1 second
6968
config.PollingInterval = time.Second
70-
default:
71-
// do nothing
7269
}
7370

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

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 {
101+
dataExporters := config.GetDataExporters()
102+
if len(dataExporters) == 0 {
103+
return 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}
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+
83149
goFF := &GoFeatureFlag{
84150
config: config,
85151
}
@@ -92,15 +158,11 @@ func New(config Config) (*GoFeatureFlag, error) {
92158
goFF.bgUpdater = newBackgroundUpdater(config.PollingInterval, config.EnablePollingJitter)
93159
goFF.cache = cache.New(notificationService, config.PersistentFlagConfigurationFile, config.internalLogger)
94160

95-
retrievers, err := config.GetRetrievers()
161+
retrieverManager, err := initializeRetrievers(config)
96162
if err != nil {
97163
return nil, err
98164
}
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
104166

105167
err = retrieveFlagsAndUpdateCache(goFF.config, goFF.cache, goFF.retrieverManager, true)
106168
if err != nil {
@@ -122,55 +184,10 @@ func New(config Config) (*GoFeatureFlag, error) {
122184

123185
go goFF.startFlagUpdaterDaemon()
124186

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.ExporterConfig, len(dataExporters))
142-
for i, de := range dataExporters {
143-
exporterConfigs[i] = exporter.ExporterConfig{
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
172-
}
187+
schedulers := initializeExporters(config)
188+
goFF.dataExporterSchedulers = schedulers
173189
}
190+
174191
config.internalLogger.Debug("GO Feature Flag is initialized")
175192
return goFF, nil
176193
}

testutils/mock/exporter_mock.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func (m *Exporter) Export(ctx context.Context, _ *fflog.FFLogger, events []expor
2626
m.ExportedEvents = append(m.ExportedEvents, events...)
2727
if m.Err != nil {
2828
if m.ExpectedNumberErr > m.CurrentNumberErr {
29+
m.ExportedEvents = m.ExportedEvents[:len(m.ExportedEvents)-len(events)]
2930
m.CurrentNumberErr++
3031
return m.Err
3132
}

0 commit comments

Comments
 (0)