Add instrumentation for measuring metrics related to visit#276
Add instrumentation for measuring metrics related to visit#276suchitadoshi1987 wants to merge 1 commit intoember-fastboot:masterfrom
Conversation
rwjblue
left a comment
There was a problem hiding this comment.
Looking good! Left a few inline comments/ideas...
| * only | ||
| */ | ||
| async getNewApplicationInstance() { | ||
| const appInstanceRetrievalStartTime = Date.now(); |
There was a problem hiding this comment.
I'd generally prefer to use something with higher precision. Mind swapping to performance.now() (docs here):
const { performance } = require('perf_hooks');
// ...snip...
const start = performance.now();There was a problem hiding this comment.
+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
| return this.getAppInstanceInfo(app, queueObject.isItemPreBuilt); | ||
| return this.getAppInstanceInfo(app, { | ||
| isAppInstancePreBuilt: queueObject.isItemPreBuilt, | ||
| appInstanceRetrievalTime: Date.now() - appInstanceRetrievalStartTime, |
There was a problem hiding this comment.
I'd like to store the start and stops too. Also can we rename this to buildAppInstanceTiming?
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.
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,
Mark
There was a problem hiding this comment.
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 start and duration is probably enough info (and addresses my primary issue).
Let's call it "dealers choice", to the PR author go the spoils 😝
There was a problem hiding this comment.
lol okk.... i will unveil the suspense in my next commit ;)
There was a problem hiding this comment.
FWIW PerformanceEntry defines startTime and duration
| let shouldBuildApp = buildSandboxPerVisit || this._applicationInstance === undefined; | ||
|
|
||
| let { app, isSandboxPreBuilt } = shouldBuildApp | ||
| let { app, appAnalytics } = shouldBuildApp |
There was a problem hiding this comment.
Can we call this analytics instead of appAnalytics?
There was a problem hiding this comment.
Also, can we unify these? Can we funnel both cases through a single function (e.g. buildAppInstance or even getNewApplicationInstance) so the rest of the code doesn't need to care about the two pathways?
There was a problem hiding this comment.
do you mean
? await this.getNewApplicationInstance()
: this.getAppInstanceInfo(this._applicationInstance);
should instead be
let { app, appAnalytics } = await this.getNewApplicationInstance(shouldBuildApp)
and the function would return the appropriate response
There was a problem hiding this comment.
Yes, IMHO we should have only a single function that is responsible for understanding:
- if we should build a new instance (based on
shouldBuildApp) - if we should build a new instance when the queue is empty and a new application instance is requested
- how to build the proper set of analytics output
| const instanceVisitStartTime = Date.now(); | ||
| await instance.visit(path, bootOptions); | ||
| result.analytics.instanceVisitTime = Date.now() - instanceVisitStartTime; |
There was a problem hiding this comment.
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,
};|
|
||
| try { | ||
| await this._visit(path, fastbootInfo, bootOptions, result, buildSandboxPerVisit); | ||
| result.analytics.fastbootVisitTime = Date.now() - fastbootVisitStartTime; |
|
@suchitadoshi1987 @rwjblue have you considered to instrument |
Ya, we definitely can (and should!) add that. We should probably make an enumerated list over in #107. |
kratiahuja
left a comment
There was a problem hiding this comment.
I believe this also needs README updates as the public API of result.analytics is being changed: https://github.com/ember-fastboot/fastboot#result
| return this.getAppInstanceInfo(app, queueObject.isItemPreBuilt); | ||
| return this.getAppInstanceInfo(app, { | ||
| isAppInstancePreBuilt: queueObject.isItemPreBuilt, | ||
| appInstanceRetrievalTime: Date.now() - appInstanceRetrievalStartTime, |
There was a problem hiding this comment.
Instead of doing this here, shouldn't these metrics come from the queueObject like isItemPreBuilt? It seems a bit of an odd API where we return whether the item was pre built or built on the fly but not the metrics of the time spent for that task. In other words, we are already getting what task was dequeued but not it's timing info.
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 dequeue API IMO.
|
|
||
| try { | ||
| await this._visit(path, fastbootInfo, bootOptions, result, buildSandboxPerVisit); | ||
| result.analytics.fastbootVisitTime = Date.now() - fastbootVisitStartTime; |
There was a problem hiding this comment.
I think visit end time is when finally block is called in order capture the entire time. Is there specific reason why we are not capturing the remaining time to build the result and shoebox?
Added instrumentation to measure