perf.js (2623B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /** 8 * @typedef {import("perf").BulkReceiving} BulkReceiving 9 */ 10 11 const { 12 FrontClassWithSpec, 13 registerFront, 14 } = require("resource://devtools/shared/protocol.js"); 15 const { perfSpec } = require("resource://devtools/shared/specs/perf.js"); 16 17 class PerfFront extends FrontClassWithSpec(perfSpec) { 18 constructor(client, targetFront, parentFront) { 19 super(client, targetFront, parentFront); 20 21 // Attribute name from which to retrieve the actorID out of the target actor's form 22 this.formAttributeName = "perfActor"; 23 } 24 25 async getProfileAndStopProfiler() { 26 const handle = await this.startCaptureAndStopProfiler(); 27 28 // Start both calls in parallel 29 const profilePromise = this.getPreviouslyCapturedProfileDataBulk(handle); 30 const additionalInformationPromise = 31 this.getPreviouslyRetrievedAdditionalInformation(handle); 32 33 // But make sure we wait until the end of both calls even in case of an error. 34 const [profileResult, additionalInformationResult] = 35 await Promise.allSettled([profilePromise, additionalInformationPromise]); 36 37 if (profileResult.status === "rejected") { 38 throw profileResult.reason; 39 } 40 41 if (additionalInformationResult.status === "rejected") { 42 throw additionalInformationResult.reason; 43 } 44 45 return { 46 profile: profileResult.value, 47 additionalInformation: additionalInformationResult.value, 48 }; 49 } 50 51 /** 52 * This implements the retrieval of the profile data using the bulk protocol. 53 * 54 * @param {number} handle THe handle returned by startCaptureAndStopProfiler 55 */ 56 async getPreviouslyCapturedProfileDataBulk(handle) { 57 /** 58 * @typedef {BulkReceiving} 59 */ 60 const profileResult = await super.getPreviouslyCapturedProfileDataBulk( 61 handle 62 ); 63 64 if (!profileResult) { 65 throw new Error( 66 "this.conn.request returns null or undefined, this is unexpected." 67 ); 68 } 69 70 if (!profileResult.length) { 71 throw new Error( 72 "The profile result is an empty buffer, this is unexpected." 73 ); 74 } 75 76 // We need to copy the data out of the stream we get using the bulk API. 77 // Note that the profile data is gzipped, but the profiler's frontend code 78 // knows how to deal with it. 79 const buffer = new ArrayBuffer(profileResult.length); 80 await profileResult.copyToBuffer(buffer); 81 return buffer; 82 } 83 } 84 85 registerFront(PerfFront);