-
Notifications
You must be signed in to change notification settings - Fork 141
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
Suspend event deliveries until middlewares are ready #552
Conversation
🦋 Changeset detectedLatest commit: b3dd757 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
cac3e8b
to
8f44a30
Compare
Changeset needed :-)
edit: OK, I see this is draft!
… On Jul 20, 2022, at 6:38 PM, changeset-bot[bot] ***@***.***> wrote:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implementation looks good to me!
@@ -0,0 +1,22 @@ | |||
export class TaskGroup { | |||
private promise!: Promise<void> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have tests that cover this? (We could also write them at the integration level).
count = 0 | ||
|
||
done = () => this.promise | ||
run = <Operation extends (...args: any[]) => any>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a non-blocking code review thing.
Another way to type this is “<ReturnT, Operation extends (…args: unknown[]) => ReturnT>(op: Operation): ReturnT
That way, we can save using the ReturnType helper, since we’re already making it ourselves.
Again, just a very mild suggestion!
5f3d4ce
to
e8e8fba
Compare
run: (op) => { | ||
const returnValue = op() | ||
|
||
if (returnValue instanceof Promise) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chrisradek alerted me to the possible gotchas of “instanceof Promise” (does not work in all environments) — there should be an “isPromise” or “isThenable” helper in utils that we used instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed up
e8e8fba
to
93d3a62
Compare
93d3a62
to
dd477cf
Compare
taskCompletionPromise = new Promise((res) => (resolvePromise = res)) | ||
} | ||
|
||
returnValue.finally(() => --count === 0 && resolvePromise()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm that the polyfill we use in the standalone version (CDN version) includes Promise.finally? I think this is the 1st time we'd be using Promise.finally outside npm-specific code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find any polyfilling at all anywhere. Tried to follow our build pipeline till the end, nothing, and no reference to core-js
either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only polyfill for the CDN version but we load a file here depending on if we determine we should polyfill -
analytics-next/packages/browser/src/browser/standalone.ts
Lines 57 to 63 in aa3c901
if (shouldPolyfill()) { | |
// load polyfills in order to get AJS to work with old browsers | |
const script = document.createElement('script') | |
script.setAttribute( | |
'src', | |
'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.7.0/polyfill.min.js' | |
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The polyfill works and makes finally
work as expected. Tested in IE11 which has no Promise support at all, but once the polyfill script is executed in the console, Promise and finally
work nominally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good to me! Just want to make sure using Promise.finally
will be safe! Alternatively could use await
with try/finally since typescript will generate that code - but I do think what you have looks cleaner.
This patch fixes an important issue where a middleware will miss out
on augmenting any events while it's being prepped up. Those events will
reach all the destinations as-is without going through the said
middleware.
With this patch,
addSourceMiddleware
is now classified as a criticaltask, and thus will seize all event deliveries until all middlewares are
in an operational state. The suspension happens internally, and the
public API is unaffected.