Bug 1444132 - Fetch stacks from content process only on-demand. r=jryans

MozReview-Commit-ID: 727tzsqkkEp

--HG--
extra : rebase_source : daad7d90a5d37145f9c17b1d98dfe2dc1b2c7c23
This commit is contained in:
Alexandre Poirot 2018-07-17 08:21:35 -07:00
parent 1d8dac53fb
commit cfe9ef4cae
6 changed files with 63 additions and 25 deletions

View File

@ -196,7 +196,7 @@ function requestsReducer(state = Requests(), action) {
* Remove the currently selected custom request.
*/
function closeCustomRequest(state) {
const { requests, selectedId } = state;
const { requests, selectedId, preselectedId } = state;
if (!selectedId) {
return state;
@ -209,10 +209,14 @@ function closeCustomRequest(state) {
return state;
}
// If the custom request is already in the Map, select it immediately,
// and reset `preselectedId` attribute.
const hasPreselectedId = preselectedId && requests.has(preselectedId);
return {
...state,
requests: mapDelete(state.requests, selectedId),
selectedId: null,
requests: mapDelete(requests, selectedId),
preselectedId: hasPreselectedId ? null : preselectedId,
selectedId: hasPreselectedId ? preselectedId : null,
};
}

View File

@ -109,7 +109,7 @@ add_task(async function() {
is(store.getState().requests.requests.size, EXPECTED_REQUESTS.length,
"All the page events should be recorded.");
EXPECTED_REQUESTS.forEach(async (spec, i) => {
EXPECTED_REQUESTS.forEach((spec, i) => {
const { method, url, causeType, causeUri, stack } = spec;
const requestItem = getSortedRequests(store.getState()).get(i);
@ -125,8 +125,6 @@ add_task(async function() {
const stacktrace = requestItem.stacktrace;
const stackLen = stacktrace ? stacktrace.length : 0;
await waitUntil(() => !!requestItem.stacktrace);
if (stack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,

View File

@ -61,8 +61,8 @@ add_task(async function() {
await waitUntil(() => {
sentItem = getSelectedRequest(store.getState());
origItem = getSortedRequests(store.getState()).get(0);
return sentItem.requestHeaders && sentItem.requestPostData &&
origItem.requestHeaders && origItem.requestPostData;
return sentItem && sentItem.requestHeaders && sentItem.requestPostData &&
origItem && origItem.requestHeaders && origItem.requestPostData;
});
await testSentRequest(sentItem, origItem);

View File

@ -103,14 +103,17 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
this._cause = networkEvent.cause;
this._fromCache = networkEvent.fromCache;
this._fromServiceWorker = networkEvent.fromServiceWorker;
this._channelId = networkEvent.channelId;
// Stack trace info isn't sent automatically. The client
// needs to request it explicitly using getStackTrace
// packet.
// packet. NetmonitorActor may pass just a boolean instead of the stack
// when the actor is in parent process and stack is in the content process.
this._stackTrace = networkEvent.cause.stacktrace;
delete networkEvent.cause.stacktrace;
networkEvent.cause.stacktraceAvailable =
!!(this._stackTrace && this._stackTrace.length);
!!(this._stackTrace &&
(typeof this._stackTrace == "boolean" || this._stackTrace.length));
for (const prop of ["method", "url", "httpVersion", "headersSize"]) {
this._request[prop] = networkEvent[prop];
@ -246,9 +249,29 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
* @return object
* The response packet - stack trace.
*/
getStackTrace() {
async getStackTrace() {
let stacktrace = this._stackTrace;
// If _stackTrace was "true", it means we are in parent process
// and the stack is available from the content process.
// Fetch it lazily from here via the message manager.
if (stacktrace && typeof stacktrace == "boolean") {
const messageManager = this.netMonitorActor.messageManager;
stacktrace = await new Promise(resolve => {
const onMessage = ({ data }) => {
const { channelId, stack } = data;
if (channelId == this._channelId) {
messageManager.removeMessageListener("debug:request-stack", onMessage);
resolve(stack);
}
};
messageManager.addMessageListener("debug:request-stack", onMessage);
messageManager.sendAsyncMessage("debug:request-stack", this._channelId);
});
this._stackTrace = stacktrace;
}
return {
stacktrace: this._stackTrace,
stacktrace,
};
},

View File

@ -49,7 +49,7 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
this.netMonitor.init();
if (this.messageManager) {
this.stackTraces = new Map();
this.stackTraces = new Set();
this.onStackTraceAvailable = this.onStackTraceAvailable.bind(this);
this.messageManager.addMessageListener("debug:request-stack-available",
this.onStackTraceAvailable);
@ -93,10 +93,11 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
},
onStackTraceAvailable(msg) {
const { channelId } = msg.data;
if (!msg.data.stacktrace) {
this.stackTraces.delete(msg.data.channelId);
this.stackTraces.delete(channelId);
} else {
this.stackTraces.set(msg.data.channelId, msg.data.stacktrace);
this.stackTraces.add(channelId);
}
},
@ -175,7 +176,10 @@ const NetworkMonitorActor = ActorClassWithSpec(networkMonitorSpec, {
this._netEvents.set(channelId, actor);
if (this.messageManager) {
event.cause.stacktrace = this.stackTraces.get(channelId);
event.cause.stacktrace = this.stackTraces.has(channelId);
if (event.cause.stacktrace) {
this.stackTraces.delete(channelId);
}
} else {
event.cause.stacktrace = this.stackTraceCollector.getStackTrace(channelId);
}

View File

@ -187,18 +187,25 @@ StackTraceCollector.prototype = {
init() {
Services.obs.addObserver(this, "http-on-opening-request");
ChannelEventSinkFactory.getService().registerCollector(this);
if (this.messageManager) {
this.onGetStack = this.onGetStack.bind(this);
this.messageManager.addMessageListener("debug:request-stack", this.onGetStack);
}
},
destroy() {
Services.obs.removeObserver(this, "http-on-opening-request");
ChannelEventSinkFactory.getService().unregisterCollector(this);
if (this.messageManager) {
this.messageManager.removeMessageListener("debug:request-stack", this.onGetStack);
}
},
_saveStackTrace(channel, stacktrace) {
if (this.messageManager) {
this.messageManager.sendAsyncMessage("debug:request-stack-available", {
channelId: channel.channelId,
stacktrace
stacktrace: stacktrace && stacktrace.length > 0
});
}
this.stacktracesById.set(channel.channelId, stacktrace);
@ -245,13 +252,6 @@ StackTraceCollector.prototype = {
const oldId = oldChannel.channelId;
const stacktrace = this.stacktracesById.get(oldId);
if (stacktrace) {
this.stacktracesById.delete(oldId);
if (this.messageManager) {
this.messageManager.sendAsyncMessage("debug:request-stack-available", {
channelId: oldId,
stacktrace: null
});
}
this._saveStackTrace(newChannel, stacktrace);
}
},
@ -260,7 +260,16 @@ StackTraceCollector.prototype = {
const trace = this.stacktracesById.get(channelId);
this.stacktracesById.delete(channelId);
return trace;
}
},
onGetStack(msg) {
const channelId = msg.data;
const stack = this.getStackTrace(channelId);
this.messageManager.sendAsyncMessage("debug:request-stack", {
channelId,
stack,
});
},
};
exports.StackTraceCollector = StackTraceCollector;