Skip to content

fix(analytics): update storage handling during keepalive flush to prevent duplicate event sends#34877

Merged
oidacra merged 2 commits intomainfrom
34357-fix
Mar 6, 2026
Merged

fix(analytics): update storage handling during keepalive flush to prevent duplicate event sends#34877
oidacra merged 2 commits intomainfrom
34357-fix

Conversation

@oidacra
Copy link
Copy Markdown
Member

@oidacra oidacra commented Mar 5, 2026

PR Description:

Summary

Fixes duplicate analytics event sends caused by keepalive flushes (page unload) skipping the storage update. The stale events left in sessionStorage were re-sent on the next
page load.

Changes Made

Frontend (SDK)

  • dot-analytics.queue.utils.ts: Removed the if (!keepalive) guard around storage cleanup after batch sends. Storage is now always updated after flushing — both for
    normal and keepalive flushes — since sessionStorage writes are synchronous and complete before page unload.
  • dot-analytics.queue.utils.spec.ts: Updated the keepalive flush test to assert that storage is cleared (previously asserted it was not), with comments explaining why.

Technical Details

The previous implementation treated keepalive flushes (triggered during visibilitychange/beforeunload) as a special case: it intentionally left sent events in
sessionStorage as a "backup" in case the beacon request failed. However, because sessionStorage.removeItem() is synchronous and guaranteed to complete before the page
unloads, this backup was unnecessary. Worse, it caused the next page load to pick up the stale persisted events and re-send them, resulting in duplicate analytics data.

The fix removes the keepalive branch so that clearStorage() / persistToStorage() always runs after a successful batch send, regardless of the flush trigger.

Breaking Changes

None

Testing

  • Unit tests updated
  • Integration tests added/updated
  • Manual testing performed
  • E2E tests added/updated

Related Issues

Closes #34357

Additional Notes

None

This PR fixes: #34357

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 5, 2026

Claude finished @oidacra's task —— View job


PR Review: Analytics Storage Handling Fix

Reviewing changes to prevent duplicate analytics event sends during keepalive flushes.

Todo List:

  • Read modified implementation file (dot-analytics.queue.utils.ts)
  • Read modified test file (dot-analytics.queue.utils.spec.ts)
  • Analyze keepalive storage logic for correctness and edge cases
  • Review test coverage and validation
  • Provide comprehensive review feedback

Review Analysis:

The fix is technically sound and addresses the duplicate event issue correctly.

Key Changes Validated:

  • Removed if (!keepalive) guard in sendBatch function (lines 240-249) - ensures storage is always updated after batch sends
  • Updated test expectations in spec file (line 835) - now correctly asserts storage is cleared during keepalive flushes
  • Added comprehensive comments explaining the synchronous nature of sessionStorage and why the backup mechanism was unnecessary

Technical Assessment:

  1. Root Cause Analysis: Correctly identified that keepalive flushes were leaving events in sessionStorage, causing next page load to re-send them
  2. Solution Logic: Sound - sessionStorage operations are indeed synchronous and complete before page unload, making the "backup" mechanism redundant
  3. Edge Cases Covered: The logic properly handles both normal and keepalive flushes consistently
  4. Test Coverage: Updated test properly validates the new behavior with clear explanatory comments

No Significant Issues Found:

  • No security concerns
  • No performance regressions
  • No breaking changes
  • Logic is consistent across all code paths
  • Error handling remains intact

The PR cleanly fixes the duplicate analytics events issue without introducing new risks.

@github-actions github-actions Bot added Area : Frontend PR changes Angular/TypeScript frontend code Area : SDK PR changes SDK libraries labels Mar 5, 2026
@nicobytes nicobytes requested a review from Copilot March 5, 2026 20:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes duplicate analytics event re-sends by ensuring the persisted queue in sessionStorage is updated/cleared even when flushing with keepalive during page unload.

Changes:

  • Removed the keepalive-only guard so storage is updated after every batch send.
  • Updated the keepalive-related unit test to expect storage clearing and documented the reasoning.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
core-web/libs/sdk/analytics/src/lib/core/shared/queue/dot-analytics.queue.utils.ts Always clears/persists sessionStorage after batching to prevent stale events from being replayed on next load.
core-web/libs/sdk/analytics/src/lib/core/shared/queue/dot-analytics.queue.utils.spec.ts Aligns keepalive flush test with the new behavior (storage cleared) to prevent duplicates.

You can also share your feedback on Copilot code review. Take the survey.

- Clarify sendBatch comment to reflect fire-and-forget nature of sendAnalyticsEvent
- Strengthen test assertions: use toHaveBeenCalledTimes(1) instead of toHaveBeenCalled()
- Clear spy before flush in normal flush test to isolate the assertion
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 5, 2026

Claude finished @oidacra's task —— View job


PR Review: Analytics Storage Handling Fix

Reviewing changes to prevent duplicate analytics event sends during keepalive flushes.

Todo List:

  • Read modified implementation file (dot-analytics.queue.utils.ts)
  • Read modified test file (dot-analytics.queue.utils.spec.ts)
  • Analyze keepalive storage logic for correctness and edge cases
  • Review test coverage and validation
  • Provide comprehensive review feedback

Review Analysis:

The fix is technically sound and addresses the duplicate event issue correctly.

Key Changes Validated:

  • Removed if (!keepalive) guard in sendBatch function (lines 240-249) - ensures storage is always updated after batch sends
  • Updated test expectations in spec file (line 835) - now correctly asserts storage is cleared during keepalive flushes
  • Added comprehensive comments explaining the synchronous nature of sessionStorage and why the backup mechanism was unnecessary

Technical Assessment:

  1. Root Cause Analysis: Correctly identified that keepalive flushes were leaving events in sessionStorage, causing next page load to re-send them
  2. Solution Logic: Sound - sessionStorage operations are indeed synchronous and complete before page unload, making the "backup" mechanism redundant
  3. Edge Cases Covered: The logic properly handles both normal and keepalive flushes consistently
  4. Test Coverage: Updated test properly validates the new behavior with clear explanatory comments

No Significant Issues Found:

  • No security concerns
  • No performance regressions
  • No breaking changes
  • Logic is consistent across all code paths
  • Error handling remains intact

The PR cleanly fixes the duplicate analytics events issue without introducing new risks.

@oidacra oidacra enabled auto-merge March 5, 2026 21:16
@oidacra oidacra added this pull request to the merge queue Mar 5, 2026
Merged via the queue into main with commit 3bf0319 Mar 6, 2026
22 checks passed
@oidacra oidacra deleted the 34357-fix branch March 6, 2026 01:40
spbolton pushed a commit that referenced this pull request Mar 24, 2026
…vent duplicate event sends (#34877)

PR Description:

  ## Summary

Fixes duplicate analytics event sends caused by keepalive flushes (page
unload) skipping the storage update. The stale events left in
`sessionStorage` were re-sent on the next
  page load.

  ## Changes Made

  ### Frontend (SDK)

- **`dot-analytics.queue.utils.ts`**: Removed the `if (!keepalive)`
guard around storage cleanup after batch sends. Storage is now always
updated after flushing — both for
normal and keepalive flushes — since `sessionStorage` writes are
synchronous and complete before page unload.
- **`dot-analytics.queue.utils.spec.ts`**: Updated the keepalive flush
test to assert that storage **is** cleared (previously asserted it was
not), with comments explaining why.

  ## Technical Details

The previous implementation treated keepalive flushes (triggered during
`visibilitychange`/`beforeunload`) as a special case: it intentionally
left sent events in
`sessionStorage` as a "backup" in case the beacon request failed.
However, because `sessionStorage.removeItem()` is synchronous and
guaranteed to complete before the page
unloads, this backup was unnecessary. Worse, it caused the next page
load to pick up the stale persisted events and re-send them, resulting
in duplicate analytics data.

The fix removes the keepalive branch so that `clearStorage()` /
`persistToStorage()` always runs after a successful batch send,
regardless of the flush trigger.

  ## Breaking Changes

  None

  ## Testing

  - [x] Unit tests updated
  - [ ] Integration tests added/updated
  - [ ] Manual testing performed
  - [ ] E2E tests added/updated

  ## Related Issues

  Closes #34357

  ## Additional Notes

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

Labels

Area : Frontend PR changes Angular/TypeScript frontend code Area : SDK PR changes SDK libraries

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Implement sessionStorage-based queue persistence for traditional web pages in Analytics SDK

4 participants