Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeError in long running timers #528

Open
alexdunae opened this issue Apr 16, 2024 · 1 comment
Open

RangeError in long running timers #528

alexdunae opened this issue Apr 16, 2024 · 1 comment

Comments

@alexdunae
Copy link

I often have long-running timers. After a timer has been running for a long time I will start to get RangeError: Property storage exceeds 196607 properties errors on iOS.

This seems to be due to Hermes setting an arbitrary number of object keys. The recommendation in the RN issue tracker is to use a Map instead of Object.

I've patched this locally. For anyone else running into the same thing... here's a diff...

diff --git a/node_modules/react-native-background-timer/android/src/main/java/com/ocetnik/timer/BackgroundTimerModule.java b/node_modules/react-native-background-timer/android/src/main/java/com/ocetnik/timer/BackgroundTimerModule.java
index 1f87803..1ea2e08 100644
--- a/node_modules/react-native-background-timer/android/src/main/java/com/ocetnik/timer/BackgroundTimerModule.java
+++ b/node_modules/react-native-background-timer/android/src/main/java/com/ocetnik/timer/BackgroundTimerModule.java
@@ -89,6 +89,16 @@ public class BackgroundTimerModule extends ReactContextBaseJavaModule {
         }, (long) timeout);
     }
 

     /*@ReactMethod
     public void clearTimeout(final int id) {
         // todo one day..
diff --git a/node_modules/react-native-background-timer/index.js b/node_modules/react-native-background-timer/index.js
index f64e4b6..fe99508 100644
--- a/node_modules/react-native-background-timer/index.js
+++ b/node_modules/react-native-background-timer/index.js
@@ -12,14 +12,15 @@ const Emitter = new NativeEventEmitter(RNBackgroundTimer);
 class BackgroundTimer {
   constructor() {
     this.uniqueId = 0;
-    this.callbacks = {};
+    this.callbacks = new Map();
 
     Emitter.addListener('backgroundTimer.timeout', (id) => {
-      if (this.callbacks[id]) {
-        const callbackById = this.callbacks[id];
-        const { callback } = callbackById;
-        if (!this.callbacks[id].interval) {
-          delete this.callbacks[id];
+      if (this.callbacks.has(id)) {
+        const callbackById = this.callbacks.get(id);
+
+        const { callback, interval, timeout } = callbackById;
+        if (!interval) {
+          this.callbacks.delete(id);
         } else {
           RNBackgroundTimer.setTimeout(id, this.callbacks[id].timeout);
         }
@@ -68,18 +69,18 @@ class BackgroundTimer {
   setTimeout(callback, timeout) {
     this.uniqueId += 1;
     const timeoutId = this.uniqueId;
-    this.callbacks[timeoutId] = {
+    this.callbacks.set(timeoutId, {
       callback,
       interval: false,
       timeout,
-    };
+    });
     RNBackgroundTimer.setTimeout(timeoutId, timeout);
     return timeoutId;
   }
 
   clearTimeout(timeoutId) {
-    if (this.callbacks[timeoutId]) {
-      delete this.callbacks[timeoutId];
+    if (this.callbacks.has(timeoutId)) {
+      this.callbacks.delete(timeoutId);
       // RNBackgroundTimer.clearTimeout(timeoutId);
     }
   }
@@ -87,18 +88,18 @@ class BackgroundTimer {
   setInterval(callback, timeout) {
     this.uniqueId += 1;
     const intervalId = this.uniqueId;
-    this.callbacks[intervalId] = {
+    this.callbacks.set(intervalId, {
       callback,
       interval: true,
       timeout,
-    };
+    });
     RNBackgroundTimer.setTimeout(intervalId, timeout);
     return intervalId;
   }
 
   clearInterval(intervalId) {
-    if (this.callbacks[intervalId]) {
-      delete this.callbacks[intervalId];
+    if (this.callbacks.has(intervalId)) {
+      this.callbacks.delete(intervalId);
       // RNBackgroundTimer.clearTimeout(intervalId);
     }
   }
@akinlekan28
Copy link

Thank you for this. Luckily I caught this before going to production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants