Skip to content

Commit 36066b2

Browse files
committed
fix: removed-trim-pipeline-buffer-to-prevent-event-loss
2 parents cd37225 + 6d5d376 commit 36066b2

2 files changed

Lines changed: 15 additions & 19 deletions

File tree

flagsmith-core.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ const Flagsmith = class {
277277

278278
const environmentKey = this.evaluationContext.environment!.apiKey;
279279
this.isPipelineFlushing = true;
280-
const eventsToSend = this.pipelineEvents;
281-
this.pipelineEvents = [];
280+
const eventsToSend = this.pipelineEvents.slice(0, this.evaluationAnalyticsMaxBuffer);
281+
this.pipelineEvents = this.pipelineEvents.slice(this.evaluationAnalyticsMaxBuffer);
282282
this.pipelineRecordedKeys.clear();
283283

284284
const batch: IPipelineEventBatch = {
@@ -302,7 +302,6 @@ const Flagsmith = class {
302302
this.log('Pipeline analytics: flush successful');
303303
} catch (err) {
304304
this.pipelineEvents = eventsToSend.concat(this.pipelineEvents);
305-
this.trimPipelineBuffer();
306305
this.log('Pipeline analytics: flush failed, events re-queued', err);
307306
} finally {
308307
this.isPipelineFlushing = false;
@@ -1008,13 +1007,6 @@ const Flagsmith = class {
10081007
this.pipelineRecordedKeys.clear();
10091008
}
10101009

1011-
private trimPipelineBuffer() {
1012-
if (this.pipelineEvents.length > this.evaluationAnalyticsMaxBuffer) {
1013-
const excess = this.pipelineEvents.length - this.evaluationAnalyticsMaxBuffer;
1014-
this.pipelineEvents = this.pipelineEvents.slice(excess);
1015-
}
1016-
}
1017-
10181010
// Pipeline event schema — must match the pipeline server's Event struct.
10191011
// To update: 1) IPipelineEvent in types.d.ts 2) event object below 3) tests in test/analytics-pipeline.test.ts
10201012
private recordPipelineEvent(key: string) {
@@ -1042,9 +1034,8 @@ const Flagsmith = class {
10421034
},
10431035
};
10441036
this.pipelineEvents.push(event);
1045-
this.trimPipelineBuffer();
10461037

1047-
if (this.pipelineFlushInterval === 0) {
1038+
if (this.pipelineFlushInterval === 0 || this.pipelineEvents.length >= this.evaluationAnalyticsMaxBuffer) {
10481039
this.flushPipelineAnalytics();
10491040
}
10501041
}

test/analytics-pipeline.test.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ describe('Pipeline Analytics', () => {
8989
});
9090
});
9191

92-
test('should cap buffer at maxBuffer and skip events when skipAnalytics is used', async () => {
93-
const { flagsmith, initConfig } = getFlagsmith({
92+
test('should flush excess events when buffer exceeds maxBuffer and skip events when skipAnalytics is used', async () => {
93+
const { flagsmith, initConfig, mockFetch } = getFlagsmith({
9494
evaluationAnalyticsConfig: {
9595
analyticsServerUrl: pipelineUrl,
9696
maxBuffer: 3,
@@ -110,12 +110,17 @@ describe('Pipeline Analytics', () => {
110110
flagsmith.getValue('number_value');
111111
flagsmith.getValue('off_value');
112112

113+
const calls = mockFetch.mock.calls.filter(([url]: [string, any]) => url.includes('v1/analytics/batch'));
114+
expect(calls).toHaveLength(1);
115+
const flushedBatch = JSON.parse(calls[0][1].body).events;
116+
expect(flushedBatch).toHaveLength(3);
117+
expect(flushedBatch[0].event_id).toBe('hero');
118+
expect(flushedBatch[2].event_id).toBe('json_value');
119+
120+
// @ts-ignore — remaining events kept for next flush
121+
expect(flagsmith.pipelineEvents).toHaveLength(2);
113122
// @ts-ignore
114-
expect(flagsmith.pipelineEvents).toHaveLength(3);
115-
// @ts-ignore
116-
expect(flagsmith.pipelineEvents[0].event_id).toBe('json_value');
117-
// @ts-ignore
118-
expect(flagsmith.pipelineEvents[2].event_id).toBe('off_value');
123+
expect(flagsmith.pipelineEvents[0].event_id).toBe('number_value');
119124
});
120125

121126
test('should deduplicate repeated evaluations with same result per flush window', async () => {

0 commit comments

Comments
 (0)