-
Notifications
You must be signed in to change notification settings - Fork 69
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
Add instrumentation for measuring metrics related to visit #276
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,8 +188,11 @@ class EmberApp { | |
* | ||
* @returns {Object} | ||
*/ | ||
getAppInstanceInfo(appInstance, isAppInstancePreBuilt = true) { | ||
return { app: appInstance, isSandboxPreBuilt: isAppInstancePreBuilt }; | ||
getAppInstanceInfo( | ||
appInstance, | ||
appAnalytics = { isAppInstancePreBuilt: true, appInstanceRetrievalTime: 0 } | ||
) { | ||
return { app: appInstance, appAnalytics }; | ||
} | ||
|
||
/** | ||
|
@@ -205,10 +208,14 @@ class EmberApp { | |
* only | ||
*/ | ||
async getNewApplicationInstance() { | ||
const appInstanceRetrievalStartTime = Date.now(); | ||
const queueObject = this._sandboxApplicationInstanceQueue.dequeue(); | ||
const app = await queueObject.item; | ||
|
||
return this.getAppInstanceInfo(app, queueObject.isItemPreBuilt); | ||
return this.getAppInstanceInfo(app, { | ||
isAppInstancePreBuilt: queueObject.isItemPreBuilt, | ||
appInstanceRetrievalTime: Date.now() - appInstanceRetrievalStartTime, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to store the start and stops too. Also can we rename this to Something like: const start = performance.now();
const queueObject = this._sandboxApplicationInstanceQueue.dequeue();
const app = await queueObject.item;
const stop = performance.now();
return this.getAppInstanceInfo(app, {
isAppInstancePreBuilt: queueObject.isItemPreBuilt,
buildAppInstanceTiming: {
start,
stop,
duration: stop - start,
}
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rob, Do we need all 3 of 'start', 'stop', and 'duration'? I'd prefer either (1) 'start' and 'stop' or (2) 'start' and 'duration'. I prefer the latter option more. The reason I like it is because: (1) it's smaller (which isn't a huge deal) and (2) whenever I see all 3 I do the subtraction to make sure 'duration' = 'stop' - 'start' because I always ask myself, why would they provide all 3? That being said, this is not such a strong opinion and if you are strongly opinionated, I'll defer. Thanks, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My reasoning here is basically that "clock time duration" isn't enough information in all cases, but in many cases it is. For example, if we just provided duration it is actually quite difficult to map the results to see how many were interleaved/overlapping/whateverTheWordIs. In general, I feel like this is in a "why not" kinda scenario (where it costs us roughly nothing to do all three, and in fact we basically have to know all three anyways in order to provide a duration). That being said, I definitely do not feel strongly about providing all 3. I think Let's call it "dealers choice", to the PR author go the spoils 😝 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol okk.... i will unveil the suspense in my next commit ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of doing this here, shouldn't these metrics come from the If it isn't prebuilt, it can capture the time to create the sandbox. This way the generator function takes care of creation of the object, determining the state of reterival and metrics. If the intent is to get the time taken to built the sanbox then it should come from as part of the |
||
}); | ||
} | ||
|
||
/** | ||
|
@@ -236,10 +243,11 @@ class EmberApp { | |
async _visit(path, fastbootInfo, bootOptions, result, buildSandboxPerVisit) { | ||
let shouldBuildApp = buildSandboxPerVisit || this._applicationInstance === undefined; | ||
|
||
let { app, isSandboxPreBuilt } = shouldBuildApp | ||
let { app, appAnalytics } = shouldBuildApp | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we call this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, can we unify these? Can we funnel both cases through a single function (e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you mean
should instead be
and the function would return the appropriate response There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, IMHO we should have only a single function that is responsible for understanding:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed! 👍 |
||
? await this.getNewApplicationInstance() | ||
: this.getAppInstanceInfo(this._applicationInstance); | ||
|
||
result.analytics.appInstanceRetrievalTime = appAnalytics.appInstanceRetrievalTime; | ||
if (buildSandboxPerVisit) { | ||
// entangle the specific application instance to the result, so it can be | ||
// destroyed when result._destroy() is called (after the visit is | ||
|
@@ -248,7 +256,7 @@ class EmberApp { | |
|
||
// we add analytics information about the current request to know | ||
// whether it used sandbox from the pre-built queue or built on demand. | ||
result.analytics.usedPrebuiltSandbox = isSandboxPreBuilt; | ||
result.analytics.usedPrebuiltSandbox = appAnalytics.isAppInstancePreBuilt; | ||
} else { | ||
// save the created application instance so that we can clean it up when | ||
// this instance of `src/ember-app.js` is destroyed (e.g. reload) | ||
|
@@ -262,7 +270,11 @@ class EmberApp { | |
registerFastBootInfo(fastbootInfo, instance); | ||
|
||
await instance.boot(bootOptions); | ||
|
||
const instanceVisitStartTime = Date.now(); | ||
await instance.visit(path, bootOptions); | ||
result.analytics.instanceVisitTime = Date.now() - instanceVisitStartTime; | ||
Comment on lines
+274
to
+276
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to above, lets use a POJO to group multiple values: const start = performance.now();
await instance.visit(path, bootOptions);
const stop = performance.now();
result.analytics.instanceVisitTimings = {
start,
stop,
duration: stop - start,
}; |
||
|
||
await fastbootInfo.deferredPromise; | ||
} | ||
|
||
|
@@ -290,6 +302,7 @@ class EmberApp { | |
* @returns {Promise<Result>} result | ||
*/ | ||
async visit(path, options) { | ||
let fastbootVisitStartTime = Date.now(); | ||
let req = options.request; | ||
let res = options.response; | ||
let html = options.html || this.html; | ||
|
@@ -323,6 +336,7 @@ class EmberApp { | |
|
||
try { | ||
await this._visit(path, fastbootInfo, bootOptions, result, buildSandboxPerVisit); | ||
result.analytics.fastbootVisitTime = Date.now() - fastbootVisitStartTime; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
|
||
if (!disableShoebox) { | ||
// if shoebox is not disabled, then create the shoebox and send API data | ||
|
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'd generally prefer to use something with higher precision. Mind swapping to
performance.now()
(docs here):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.
+1 to
performance.now()
, not only higher precision, more importantly it's using a monotonic clock therefore it is not subject to system clock skew or adjustments https://www.w3.org/TR/hr-time-2/#sec-monotonic-clock