@@ -25,8 +25,10 @@ import {
25
25
import { Options , Target } from './types' ;
26
26
import { VERSION } from './version' ;
27
27
import {
28
+ infoEvaluationMetricsExceeded ,
28
29
infoMetricsSuccess ,
29
30
infoMetricsThreadExited ,
31
+ infoTargetMetricsExceeded ,
30
32
warnPostMetricsFailed ,
31
33
} from './sdk_codes' ;
32
34
import { Logger } from './log' ;
@@ -63,6 +65,9 @@ export class MetricsProcessor implements MetricsProcessorInterface {
63
65
// Maximum sizes for caches
64
66
private MAX_EVALUATION_ANALYTICS_SIZE = 10000 ;
65
67
private MAX_TARGET_ANALYTICS_SIZE = 100000 ;
68
+ private evaluationAnalyticsExceeded = false ;
69
+ private targetAnalyticsExceeded = false ;
70
+
66
71
private syncInterval ?: NodeJS . Timeout ;
67
72
private api : MetricsApi ;
68
73
private readonly log : Logger ;
@@ -118,28 +123,48 @@ export class MetricsProcessor implements MetricsProcessorInterface {
118
123
variation,
119
124
count : 0 ,
120
125
} ;
126
+ this . storeEvaluationAnalytic ( event ) ;
127
+ this . storeTargetAnalytic ( target ) ;
128
+ }
121
129
122
- if ( this . evaluationAnalytics . size < this . MAX_EVALUATION_ANALYTICS_SIZE ) {
123
- const key = this . _formatKey ( event ) ;
124
- const found = this . evaluationAnalytics . get ( key ) ;
125
- if ( found ) {
126
- found . count ++ ;
127
- } else {
128
- event . count = 1 ;
129
- this . evaluationAnalytics . set ( key , event ) ;
130
+ private storeTargetAnalytic ( target : Target ) {
131
+ if ( this . targetAnalytics . size >= this . MAX_TARGET_ANALYTICS_SIZE ) {
132
+ if ( ! this . targetAnalyticsExceeded ) {
133
+ this . targetAnalyticsExceeded = true ;
134
+ infoTargetMetricsExceeded ( this . log ) ;
130
135
}
136
+
137
+ return ;
131
138
}
132
139
133
- if ( this . targetAnalytics . size < this . MAX_TARGET_ANALYTICS_SIZE ) {
134
- if ( target && ! target . anonymous ) {
135
- // If target has been seen then ignore it
136
- if ( this . seenTargets . has ( target . identifier ) ) {
137
- return ;
138
- }
140
+ if ( target && ! target . anonymous ) {
141
+ // If target has been seen then ignore it
142
+ if ( this . seenTargets . has ( target . identifier ) ) {
143
+ return ;
144
+ }
145
+
146
+ this . seenTargets . add ( target . identifier ) ;
147
+ this . targetAnalytics . set ( target . identifier , target ) ;
148
+ }
149
+ }
139
150
140
- this . seenTargets . add ( target . identifier ) ;
141
- this . targetAnalytics . set ( target . identifier , target ) ;
151
+ private storeEvaluationAnalytic ( event : AnalyticsEvent ) {
152
+ if ( this . evaluationAnalytics . size >= this . MAX_EVALUATION_ANALYTICS_SIZE ) {
153
+ if ( ! this . evaluationAnalyticsExceeded ) {
154
+ this . evaluationAnalyticsExceeded = true ;
155
+ infoEvaluationMetricsExceeded ( this . log ) ;
142
156
}
157
+
158
+ return ;
159
+ }
160
+
161
+ const key = this . _formatKey ( event ) ;
162
+ const found = this . evaluationAnalytics . get ( key ) ;
163
+ if ( found ) {
164
+ found . count ++ ;
165
+ } else {
166
+ event . count = 1 ;
167
+ this . evaluationAnalytics . set ( key , event ) ;
143
168
}
144
169
}
145
170
@@ -159,6 +184,8 @@ export class MetricsProcessor implements MetricsProcessorInterface {
159
184
const clonedTargetAnalytics = new Map ( this . targetAnalytics ) ;
160
185
this . evaluationAnalytics . clear ( ) ;
161
186
this . targetAnalytics . clear ( ) ;
187
+ this . evaluationAnalyticsExceeded = false ;
188
+ this . targetAnalyticsExceeded = false ;
162
189
163
190
clonedEvaluationAnalytics . forEach ( ( event ) => {
164
191
const metricsAttributes : KeyValue [ ] = [
0 commit comments