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

feat: add sendBeacon support #412

Merged
merged 12 commits into from
Aug 13, 2021
Merged

feat: add sendBeacon support #412

merged 12 commits into from
Aug 13, 2021

Conversation

ajhorst
Copy link
Contributor

@ajhorst ajhorst commented Jul 27, 2021

Summary

  • add support for using sendBeacon instead of xhr to send data
  • add a convenience method option to log with beacon when a user exits the browser

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?: No

AJ Horst added 3 commits July 26, 2021 22:17
- add transport as option (either http or beacon)
- support sending event with either transport mechanism
@ajhorst ajhorst requested review from jooohhn and kelvin-lu and removed request for jooohhn July 27, 2021 16:24
@ajhorst ajhorst changed the title Amp 13223 beacon support feat(beacon): add sendBeacon support (AMP-13223) Jul 27, 2021
@ajhorst ajhorst changed the title feat(beacon): add sendBeacon support (AMP-13223) feat(beacon): add sendBeacon support Jul 27, 2021
@ajhorst ajhorst changed the title feat(beacon): add sendBeacon support feat: add sendBeacon support Jul 27, 2021
@ajhorst
Copy link
Contributor Author

ajhorst commented Jul 29, 2021

Updated the confluence doc on sendBeacon to describe what I'm going for with this PR: https://amplitude.atlassian.net/wiki/spaces/sdk/pages/1492058287/Beacon+API+-+JS+SDK+Proposal#Implementation%3A

@ajhorst ajhorst changed the title feat: add sendBeacon support feat: add sendBeacon support Jul 30, 2021
@lgtm-com
Copy link

lgtm-com bot commented Jul 30, 2021

This pull request introduces 28 alerts when merging 7902a98 into 564f656 - view on LGTM.com

new alerts:

  • 9 for Property access on null or undefined
  • 4 for Useless conditional
  • 4 for Incomplete string escaping or encoding
  • 3 for Unneeded defensive code
  • 2 for Useless assignment to local variable
  • 2 for Duplicate character in character class
  • 2 for Unused variable, import, function or class
  • 2 for Insecure randomness

@ajhorst ajhorst requested review from tevanko and removed request for tevanko August 9, 2021 18:27
@@ -1633,6 +1688,23 @@ AmplitudeClient.prototype.sendEvents = function sendEvents() {
checksum: md5(Constants.API_VERSION + this.options.apiKey + events + uploadTime),
};

if (!navigator.sendBeacon) {
Copy link
Contributor

Choose a reason for hiding this comment

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

hm, I think I would expect this in the validateTransport function and not in sendEvents

const handleVisibilityChange = () => {
const prevTransport = this.options.transport;
this.setTransport(Constants.TRANSPORT_BEACON);
onExitPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

thoughts on hooking the current object with onExitPage(this) allowing users to access the client earlier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As in, so they can write the callback on a line before initializing the client with it? The way I was testing it, as long as the amplitude object is in scope within the file, it doesn't need to be initialized until onExitPage is called. So the following is fine:

const onExitPage = () => {
      amplitude.getInstance().logEvent('logging onExitPage');
    };

    amplitude.getInstance().init('API_KEY', userID, { onExitPage });

But if there's another benefit you're thinking of by making the client an argument, it would be an easy change to make

Copy link
Contributor

Choose a reason for hiding this comment

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

It might make it easier for people using the snippet to use the full client obj (incl. "private" methods and the full list of options post-init to construct event properties) but you are right that everything publicly supported is available.

I don't feel too strongly about this though so we can not do this and see what people actually want as arguments to this option!

this.options.transport = Constants.TRANSPORT_HTTP;
}

if (this.options.transport === Constants.TRANSPORT_BEACON) {
Copy link
Contributor

Choose a reason for hiding this comment

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

might be too much, but would be good to replace a lot of these with a small descriptive helper function like doesTransportSupportSaveEvents

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried adding helper functions, but since there are only two transports now, they didn't add much descriptivity compared to checking the value itself. If there end up being more than two, then definitely there should be helper functions to categorize them like this

@@ -108,6 +108,18 @@ const validateDeviceId = function validateDeviceId(deviceId) {
return true;
};

const validateTransport = function validateTransport(transport) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this checked on initialization? In case it comes in bad

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's not but it should be, good call

Copy link
Contributor

@kelvin-lu kelvin-lu left a comment

Choose a reason for hiding this comment

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

Not super familiar with our build system as of now, but why is this PR adding 2 5k sized files?

@ajhorst
Copy link
Contributor Author

ajhorst commented Aug 11, 2021

@kelvin-lu those files were built while I was testing this PR locally and weren't in the gitignore, so I accidentally committed them. I just now took them out of the PR and added them to the gitignore

@ajhorst ajhorst requested a review from kelvin-lu August 13, 2021 17:29
Copy link
Contributor

@kelvin-lu kelvin-lu left a comment

Choose a reason for hiding this comment

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

overall lgtm!

I think the only other thing DX wise is some sort of warning that the Transport Beacon does not retry like regular XHR requests. I feel like that might be a source of questions/data governance concerns

return this._q.push(['setTransport'].concat(Array.prototype.slice.call(arguments, 0)));
}

const t = transport.toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure how to manage this in validateTransport but you should probably check that this is a string before using toLowerCase

Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps like validateProperties we coudl have validateTransport return a sanitary version of the string? :)

@ajhorst
Copy link
Contributor Author

ajhorst commented Aug 13, 2021

That's an interesting point RE DX. I have a followup ticket to update the dev docs with instructions for sendBeacon, so I'll definitely mention the lack of retry.

@ajhorst
Copy link
Contributor Author

ajhorst commented Aug 13, 2021

I'll tighten up validateTransport like you suggest and then merge

@ajhorst ajhorst merged commit 0517038 into main Aug 13, 2021
@ajhorst ajhorst deleted the AMP-13223_beacon_support branch August 13, 2021 22:04
github-actions bot pushed a commit that referenced this pull request Aug 13, 2021
# [8.5.0](v8.4.0...v8.5.0) (2021-08-13)

### Bug Fixes

* LGTM return fix for falsy str ([#416](#416)) ([f744fe7](f744fe7))

### Features

* add sendBeacon support ([#412](#412)) ([0517038](0517038))
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.

2 participants