Skip to content

Commit 0e189da

Browse files
committed
FFM-11660 Move seen targets clear interval to analytics
FFM-11660 Add comment FFM-11660 Add Bump version FFM-11660 Add a stop clearing method
1 parent 28b5889 commit 0e189da

File tree

4 files changed

+42
-36
lines changed

4 files changed

+42
-36
lines changed

.harness/ffgolangserversdk.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ pipeline:
176176
dockerfile: ff-sdk-testgrid/go/Dockerfile
177177
context: ff-sdk-testgrid/go
178178
buildArgs:
179-
SDK_VERSION: v0.1.24
179+
SDK_VERSION: v0.1.25
180180
BUILD_MODE: local
181181
resources:
182182
limits:

analyticsservice/analytics.go

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const (
2626
variationValueAttribute string = "featureValue"
2727
targetAttribute string = "target"
2828
sdkVersionAttribute string = "SDK_VERSION"
29-
SdkVersion string = "0.1.24"
29+
SdkVersion string = "0.1.25"
3030
sdkTypeAttribute string = "SDK_TYPE"
3131
sdkType string = "server"
3232
sdkLanguageAttribute string = "SDK_LANGUAGE"
@@ -62,16 +62,17 @@ type analyticsEvent struct {
6262

6363
// AnalyticsService provides a way to cache and send analytics to the server
6464
type AnalyticsService struct {
65-
analyticsChan chan analyticsEvent
66-
evaluationAnalytics SafeAnalyticsCache[string, analyticsEvent]
67-
targetAnalytics SafeAnalyticsCache[string, evaluation.Target]
68-
seenTargets SafeSeenTargetsCache[string, bool]
69-
logEvaluationLimitReached atomic.Bool
70-
logTargetLimitReached atomic.Bool
71-
timeout time.Duration
72-
logger logger.Logger
73-
metricsClient metricsclient.ClientWithResponsesInterface
74-
environmentID string
65+
analyticsChan chan analyticsEvent
66+
evaluationAnalytics SafeAnalyticsCache[string, analyticsEvent]
67+
targetAnalytics SafeAnalyticsCache[string, evaluation.Target]
68+
seenTargets SafeSeenTargetsCache[string, bool]
69+
logEvaluationLimitReached atomic.Bool
70+
logTargetLimitReached atomic.Bool
71+
timeout time.Duration
72+
logger logger.Logger
73+
metricsClient metricsclient.ClientWithResponsesInterface
74+
environmentID string
75+
seenTargetsClearingInterval time.Duration
7576
}
7677

7778
// NewAnalyticsService creates and starts a analytics service to send data to the client
@@ -83,12 +84,13 @@ func NewAnalyticsService(timeout time.Duration, logger logger.Logger, seenTarget
8384
serviceTimeout = 1 * time.Hour
8485
}
8586
as := AnalyticsService{
86-
analyticsChan: make(chan analyticsEvent),
87-
evaluationAnalytics: newSafeEvaluationAnalytics(),
88-
targetAnalytics: newSafeTargetAnalytics(),
89-
seenTargets: newSafeSeenTargets(seenTargetsMaxSize, seenTargetsClearingSchedule),
90-
timeout: serviceTimeout,
91-
logger: logger,
87+
analyticsChan: make(chan analyticsEvent),
88+
evaluationAnalytics: newSafeEvaluationAnalytics(),
89+
targetAnalytics: newSafeTargetAnalytics(),
90+
seenTargets: newSafeSeenTargets(seenTargetsMaxSize),
91+
timeout: serviceTimeout,
92+
logger: logger,
93+
seenTargetsClearingInterval: seenTargetsClearingSchedule,
9294
}
9395
go as.listener()
9496

@@ -101,6 +103,7 @@ func (as *AnalyticsService) Start(ctx context.Context, client metricsclient.Clie
101103
as.metricsClient = client
102104
as.environmentID = environmentID
103105
go as.startTimer(ctx)
106+
go as.startSeenTargetsClearingSchedule(ctx, as.seenTargetsClearingInterval)
104107
}
105108

106109
func (as *AnalyticsService) startTimer(ctx context.Context) {
@@ -110,6 +113,7 @@ func (as *AnalyticsService) startTimer(ctx context.Context) {
110113
timeStamp := time.Now().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond))
111114
as.sendDataAndResetCache(ctx, timeStamp)
112115
case <-ctx.Done():
116+
close(as.analyticsChan)
113117
as.logger.Infof("%s Metrics stopped", sdk_codes.MetricsStopped)
114118
return
115119
}
@@ -324,6 +328,22 @@ func (as *AnalyticsService) processTargetMetrics(targetAnalytics SafeAnalyticsCa
324328
return targetData
325329
}
326330

331+
func (as *AnalyticsService) startSeenTargetsClearingSchedule(ctx context.Context, clearingInterval time.Duration) {
332+
ticker := time.NewTicker(clearingInterval)
333+
334+
for {
335+
select {
336+
case <-ticker.C:
337+
as.logger.Infof("Clearing seen targets")
338+
as.seenTargets.clear()
339+
340+
case <-ctx.Done():
341+
ticker.Stop()
342+
return
343+
}
344+
}
345+
}
346+
327347
func getEvaluationAnalyticKey(event analyticsEvent) string {
328348
return fmt.Sprintf("%s-%s-%s-%s", event.featureConfig.Feature, event.variation.Identifier, event.variation.Value, globalTarget)
329349
}

analyticsservice/safe_seen_targets_map.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,21 @@ package analyticsservice
33
import (
44
"sync"
55
"sync/atomic"
6-
"time"
76
)
87

98
type safeSeenTargets struct {
109
sync.RWMutex
1110
data map[string]bool
1211
maxSize int
1312
limitExceeded atomic.Bool
14-
clearingTimer *time.Ticker
1513
}
1614

1715
// Implements SafeSeenTargetsCache
18-
func newSafeSeenTargets(maxSize int, clearingInterval time.Duration) SafeSeenTargetsCache[string, bool] {
19-
st := &safeSeenTargets{
16+
func newSafeSeenTargets(maxSize int) SafeSeenTargetsCache[string, bool] {
17+
return &safeSeenTargets{
2018
data: make(map[string]bool),
2119
maxSize: maxSize,
2220
}
23-
24-
if clearingInterval > 0 {
25-
st.clearingTimer = time.NewTicker(clearingInterval)
26-
27-
// Start a goroutine to clear the cache at a set interval
28-
go func() {
29-
for range st.clearingTimer.C {
30-
st.clear()
31-
}
32-
}()
33-
}
34-
35-
return st
3621
}
3722

3823
func (s *safeSeenTargets) setWithLimit(key string, seen bool) {

client/options.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ func WithSeenTargetsMaxSize(maxSize int) ConfigOption {
156156
}
157157
}
158158

159-
// WithSeenTargetsClearInterval sets the clearing interval for the seen targets map.
159+
// WithSeenTargetsClearInterval sets the clearing interval for the seen targets map. By default, the interval
160+
// is set to 24 hours.
160161
func WithSeenTargetsClearInterval(interval time.Duration) ConfigOption {
161162
return func(config *config) {
162163
config.seenTargetsClearInterval = interval

0 commit comments

Comments
 (0)