segmentio / analytics-react-native

The hassle-free way to add analytics to your React-Native app.
https://segment.com/docs/sources/mobile/react-native/
MIT License
360 stars 185 forks source link

Expose an API that allows events in the store to be cleared #850

Open Aitchy13 opened 1 year ago

Aitchy13 commented 1 year ago

Summary

When events are blocked by the client or by the network it's connected to, the events that weren't able to be flushed continue to be written locally and grow every time a new event is triggered. Over time this can cause the user to have thousands of their events stored locally, waiting to be retried, which lead to slower reads and writes. We've noticed this performance bottleneck in our project, and have confirmed that clearing the events out for the user has immediately alleviate the performance issue they were having.

Proposed Solution

In this situation, it appears as though the SegmentDestination and QueueFlushingPlugin have a handle on the store. As such, I propose that we expose methods that allow you to clear the store via those plugins.

Below is small patch that exposes the necessary methods which allow you to clear the store yourself.

diff --git a/node_modules/@segment/analytics-react-native/src/plugins/QueueFlushingPlugin.ts b/node_modules/@segment/analytics-react-native/src/plugins/QueueFlushingPlugin.ts
index 7fc3e93..35f1baf 100644
--- a/node_modules/@segment/analytics-react-native/src/plugins/QueueFlushingPlugin.ts
+++ b/node_modules/@segment/analytics-react-native/src/plugins/QueueFlushingPlugin.ts
@@ -91,4 +91,13 @@ export class QueueFlushingPlugin extends UtilityPlugin {
       return { events: filteredEvents };
     });
   }
+
+  /**
+   * Removes all events from the queue
+   */
+  clear() {
+    this.queueStore?.dispatch((state) => {
+      return { events: [] }
+    })
+  }
 }
diff --git a/node_modules/@segment/analytics-react-native/src/plugins/SegmentDestination.ts b/node_modules/@segment/analytics-react-native/src/plugins/SegmentDestination.ts
index 54e81f6..db1b356 100644
--- a/node_modules/@segment/analytics-react-native/src/plugins/SegmentDestination.ts
+++ b/node_modules/@segment/analytics-react-native/src/plugins/SegmentDestination.ts
@@ -117,4 +117,8 @@ export class SegmentDestination extends DestinationPlugin {
   async flush() {
     return this.queuePlugin.flush();
   }
+
+  clearEvents() {
+    return this.queuePlugin.clear()
+  }
 }

It would also be useful to expose methods that let you count how many events are in the store, so it is easier to get a handle on when you might want to clear the events out.

oscb commented 1 year ago

Hey @Aitchy13

Thanks for such a well documented enhancement idea. I will put this in our plans as it sounds very useful!

gaberogan commented 6 months ago

I haven't tried this solution in production nor solved this issue yet, but one thing that looks suspicious is that the events are all simulataneously sent rather than making one request at a time:

Screenshot 2024-04-04 at 3 45 44 PM

I know for a fact there is a serious performance issue somewhere because there are 100K+ segment events taking longer than 10 seconds, and looking at device logs they are all getting sent at the same time.

Screenshot 2024-04-04 at 2 19 19 PM