Skip to content

Commit 9fc9550

Browse files
authored
fix: stop accumulating bad events
This reverts commit 043987f.
1 parent 790311c commit 9fc9550

File tree

2 files changed

+17
-71
lines changed

2 files changed

+17
-71
lines changed

packages/analytics-core/src/plugins/destination.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export class Destination implements DestinationPlugin {
5959

6060
this.storageKey = `${STORAGE_PREFIX}_${this.config.apiKey.substring(0, 10)}`;
6161
const unsent = await this.config.storageProvider?.get(this.storageKey);
62+
this.saveEvents(); // sets storage to '[]'
6263
if (unsent && unsent.length > 0) {
6364
void Promise.all(unsent.map((event) => this.execute(event))).catch();
6465
}
@@ -82,7 +83,6 @@ export class Destination implements DestinationPlugin {
8283
const tryable = list.filter((context) => {
8384
if (context.attempts < this.config.flushMaxRetries) {
8485
context.attempts += 1;
85-
8686
return true;
8787
}
8888
void this.fulfillRequest([context], 500, MAX_RETRIES_EXCEEDED_MESSAGE);
@@ -102,7 +102,7 @@ export class Destination implements DestinationPlugin {
102102
}, context.timeout);
103103
});
104104

105-
void this.updateEventStorage([], this.queue);
105+
this.saveEvents();
106106
}
107107

108108
schedule(timeout: number) {
@@ -186,19 +186,19 @@ export class Destination implements DestinationPlugin {
186186

187187
switch (status) {
188188
case Status.Success: {
189-
void this.handleSuccessResponse(res, list);
189+
this.handleSuccessResponse(res, list);
190190
break;
191191
}
192192
case Status.Invalid: {
193-
void this.handleInvalidResponse(res, list);
193+
this.handleInvalidResponse(res, list);
194194
break;
195195
}
196196
case Status.PayloadTooLarge: {
197-
void this.handlePayloadTooLargeResponse(res, list);
197+
this.handlePayloadTooLargeResponse(res, list);
198198
break;
199199
}
200200
case Status.RateLimit: {
201-
void this.handleRateLimitResponse(res, list);
201+
this.handleRateLimitResponse(res, list);
202202
break;
203203
}
204204
default: {
@@ -241,7 +241,6 @@ export class Destination implements DestinationPlugin {
241241
// log intermediate event status before retry
242242
this.config.loggerProvider.warn(getResponseBodyString(res));
243243
}
244-
245244
this.addToQueue(...retry);
246245
}
247246

@@ -298,37 +297,21 @@ export class Destination implements DestinationPlugin {
298297
}
299298

300299
fulfillRequest(list: Context[], code: number, message: string) {
300+
this.saveEvents();
301301
list.forEach((context) => context.callback(buildResult(context.event, code, message)));
302-
void this.updateEventStorage(list);
303302
}
304303

305304
/**
305+
* Saves events to storage
306306
* This is called on
307307
* 1) new events are added to queue; or
308308
* 2) response comes back for a request
309-
*
310-
* update the event storage
311309
*/
312-
async updateEventStorage(eventsToRemove: Context[], eventsToAdd?: Context[]) {
310+
saveEvents() {
313311
if (!this.config.storageProvider) {
314312
return;
315313
}
316-
317-
const filterEventInsertIdSet = eventsToRemove.reduce((filtered, context) => {
318-
if (context.event.insert_id) {
319-
filtered.add(context.event.insert_id);
320-
}
321-
return filtered;
322-
}, new Set<string>());
323-
324-
const savedEvents = await this.config.storageProvider.get(this.storageKey);
325-
const updatedEvents: Event[] = eventsToAdd?.map((context) => context.event) || [];
326-
327-
savedEvents?.forEach((event) => {
328-
if (event.insert_id && !filterEventInsertIdSet.has(event.insert_id)) {
329-
updatedEvents.push(event);
330-
}
331-
});
332-
await this.config.storageProvider.set(this.storageKey, updatedEvents);
314+
const events = Array.from(this.queue.map((context) => context.event));
315+
void this.config.storageProvider.set(this.storageKey, events);
333316
}
334317
}

packages/analytics-core/test/plugins/destination.test.ts

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -548,15 +548,8 @@ describe('destination', () => {
548548
});
549549
});
550550

551-
describe('filterEvent', () => {
552-
test('should be ok with no storage provider', async () => {
553-
const destination = new Destination();
554-
destination.config = useDefaultConfig();
555-
destination.config.storageProvider = undefined;
556-
expect(await destination.updateEventStorage([])).toBe(undefined);
557-
});
558-
559-
test('should filter dropped event and update the storage provider', async () => {
551+
describe('saveEvents', () => {
552+
test('should save to storage provider', () => {
560553
const destination = new Destination();
561554
destination.config = useDefaultConfig();
562555
destination.config.storageProvider = {
@@ -567,46 +560,16 @@ describe('destination', () => {
567560
reset: async () => undefined,
568561
getRaw: async () => undefined,
569562
};
570-
const event1 = { event_type: 'event', insert_id: '1' };
571-
const event2 = { event_type: 'filtered_event', insert_id: '2' };
572-
const get = jest.spyOn(destination.config.storageProvider, 'get').mockResolvedValueOnce([event1, event2]);
573563
const set = jest.spyOn(destination.config.storageProvider, 'set').mockResolvedValueOnce(undefined);
574-
const context = {
575-
event: event2,
576-
attempts: 0,
577-
callback: () => undefined,
578-
timeout: 0,
579-
};
580-
await destination.updateEventStorage([context]);
581-
expect(get).toHaveBeenCalledTimes(1);
564+
destination.saveEvents();
582565
expect(set).toHaveBeenCalledTimes(1);
583-
expect(set).toHaveBeenCalledWith('', expect.objectContaining([event1]));
584566
});
585567

586-
test('should save event to the storage provider', async () => {
568+
test('should be ok with no storage provider', () => {
587569
const destination = new Destination();
588570
destination.config = useDefaultConfig();
589-
destination.config.storageProvider = {
590-
isEnabled: async () => true,
591-
get: async () => undefined,
592-
set: async () => undefined,
593-
remove: async () => undefined,
594-
reset: async () => undefined,
595-
getRaw: async () => undefined,
596-
};
597-
const event = { event_type: 'event', insert_id: '1' };
598-
const get = jest.spyOn(destination.config.storageProvider, 'get').mockResolvedValueOnce([]);
599-
const set = jest.spyOn(destination.config.storageProvider, 'set').mockResolvedValueOnce(undefined);
600-
const context = {
601-
event: event,
602-
attempts: 0,
603-
callback: () => undefined,
604-
timeout: 0,
605-
};
606-
await destination.updateEventStorage([], [context]);
607-
expect(get).toHaveBeenCalledTimes(1);
608-
expect(set).toHaveBeenCalledTimes(1);
609-
expect(set).toHaveBeenCalledWith('', expect.objectContaining([event]));
571+
destination.config.storageProvider = undefined;
572+
expect(destination.saveEvents()).toBe(undefined);
610573
});
611574
});
612575

0 commit comments

Comments
 (0)