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

Increases specificity of localStorage keys to differentiate events by writeKey #861

Merged
merged 3 commits into from
May 31, 2023

Conversation

chrisradek
Copy link
Contributor

This PR adds the writeKey used to configure analytics.js to the PersistedPriorityQueue localStorage keys.

This prevents 2 analytics.js instances configured with different writeKeys but installed on the same domain (e.g. https://foo.segment.com/app1 with writeKey foo, https://foo.segment.com/app2 with writeKey bar) from reading each others retried events from localStorage.

Analytics.js saves events to localStorage when a user navigates away from a page that has events that haven't been sent to destinations/Segment.

Special Notes

  • classic integrations can also persist events to localStorage, so this led me to piping writeKey to a lot more places than I hoped.
  • I thought about handling the fallback scenario where an end-user was just upgraded to the latest version of this library and had events in localStorage using the old key format. (Even wrote a test for it initially...)
    I backed those changes out because it's extra tech debt that should only be needed for about a week, and I was worried it would make this issue still possible if a page in the domain was using a version of analytics.js that persisted to the old key.

Testing

I added playwright tests that will execute the conditions that trigger events to be sent to localStorage.

[x] I've included a changeset (psst. run yarn changeset. Read about changesets here).

@changeset-bot
Copy link

changeset-bot bot commented May 16, 2023

🦋 Changeset detected

Latest commit: 53799f0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@segment/analytics-next Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@@ -86,16 +86,17 @@ function mutex(key: string, onUnlock: Function, attempt = 0): void {
}

export class PersistedPriorityQueue extends PriorityQueue<Context> {
constructor(maxAttempts: number, key: string) {
constructor(maxAttempts: number, key: string, writeKey: string) {
Copy link
Contributor

@silesky silesky May 16, 2023

Choose a reason for hiding this comment

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

Nit: While I think you only made this choice because EventQueue can take a configured priorityQueue, I can't help but feel there is something off about this class knowing what a writeKey is... "domain" concept seeping into the ostensibly generic "lib". It never uses the writeKey by itself. Perhaps a new "AnalyticsPersistedPriorityQueue" subclass would be better. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally required it to handle the fallback case of reading keys that didn't include the writeKey, but I can remove that from this now. It did give me the benefit of having TypeScript yell at me if any usage didn't include the writekey though, but that work is done now.


expect(persistedItems).toHaveLength(1)
expect(persistedItems[0].writeKey).toBe('key2')
expect(persistedItems[0].messageIds).toStrictEqual([messageId2])
Copy link
Contributor

@silesky silesky May 16, 2023

Choose a reason for hiding this comment

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

This whole test... 🤩

import {
PersistedQueueResult,
getPersistedItems,
} from './helpers/get-persisted-items'

test.describe('Standalone tests', () => {
Copy link
Contributor

@silesky silesky May 16, 2023

Choose a reason for hiding this comment

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

Was this meant to be the suite name, or is this copypasta?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooph, I think it was meant to signify these tests are for the standalone (CDN) version of a.js, not the NPM version. Can probably remove this describe block though.

Copy link
Contributor

@danieljackins danieljackins left a comment

Choose a reason for hiding this comment

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

LGTM!

@chrisradek chrisradek merged commit 99402e9 into master May 31, 2023
@chrisradek chrisradek deleted the fix-multi-wk-retries branch May 31, 2023 16:49
@github-actions github-actions bot mentioned this pull request May 31, 2023
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

Successfully merging this pull request may close these issues.

3 participants