Skip to content

[Feature] Add retry limit and backoff to InteractionTracker event submission #67

Description

@numbers-official

Summary

The InteractionTracker.createEvent() method in src/modal/interaction-tracker.ts retries indefinitely when the authentication token has not yet been fetched, creating a potential resource leak and degraded user experience on slow or failing networks.

Affected File

src/modal/interaction-tracker.ts — Lines 44–56

Details

When this.token is null (token fetch still in progress), the createEvent method recursively schedules itself via setTimeout every 1 second with no retry limit:

private createEvent(name, datetime, nid, subid): void {
  const token = this.token;
  if (token === null) {
    setTimeout(() => {
      this.createEvent(name, datetime, nid, subid);
    }, 1000);
    return;
  }
  // ...
}

If the token fetch takes a long time or the CDN is unreachable, every tracked interaction queues an unbounded retry chain. On a page with multiple capture-eye elements, this compounds:

  • N elements x M interactions x unlimited retries = significant accumulated setTimeout callbacks
  • Each retry closure retains references to its arguments, preventing garbage collection
  • On mobile devices with limited resources, this degrades performance

Proposed Approach

  1. Add a max retry count (e.g., 5 retries) with exponential backoff (1s, 2s, 4s, 8s, 16s):
private createEvent(name, datetime, nid, subid, retryCount = 0): void {
  const MAX_RETRIES = 5;
  const token = this.token;
  if (token === null) {
    if (retryCount >= MAX_RETRIES) {
      console.warn('Event tracking abandoned after max retries:', name);
      return;
    }
    const delay = Math.min(1000 * Math.pow(2, retryCount), 16000);
    setTimeout(() => {
      this.createEvent(name, datetime, nid, subid, retryCount + 1);
    }, delay);
    return;
  }
  // ...
}
  1. Optional: Queue events instead of retrying each individually. Buffer events in an array and flush the queue once the token becomes available, avoiding per-event retry chains entirely.

Expected Impact

  • Prevents unbounded retry loops on slow/unreachable networks
  • Reduces memory pressure from accumulated closures on pages with many capture-eye instances
  • Graceful degradation: analytics are best-effort, not blocking
  • No breaking changes to public API
  • Estimated effort: 1-2 hours

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions