Revert D5470356: [react-native] Increase information logged to MessageQueue.spy

Differential Revision: D5470356

fbshipit-source-id: 27b247ac3c538f801c1f9a86f74fb3098064e92e
This commit is contained in:
Kody Greenbaum 2017-07-25 11:51:12 -07:00 committed by Facebook Github Bot
parent 6e28b39d78
commit 26764d4179
4 changed files with 61 additions and 157 deletions

View File

@ -8,12 +8,10 @@
* *
* @providesModule BatchedBridge * @providesModule BatchedBridge
* @flow * @flow
* @format
*/ */
'use strict'; 'use strict';
const MessageQueue = require('MessageQueue'); const MessageQueue = require('MessageQueue');
const BatchedBridge = new MessageQueue(); const BatchedBridge = new MessageQueue();
// Wire up the batched bridge on the global object so that we can call into it. // Wire up the batched bridge on the global object so that we can call into it.

View File

@ -8,7 +8,6 @@
* *
* @providesModule MessageQueue * @providesModule MessageQueue
* @flow * @flow
* @format
*/ */
/*eslint no-bitwise: 0*/ /*eslint no-bitwise: 0*/
@ -25,13 +24,9 @@ const stringifySafe = require('stringifySafe');
export type SpyData = { export type SpyData = {
type: number, type: number,
module: ?string, module: ?string,
method: string | number, method: string|number,
isSync: boolean, args: any
successCbId: number, }
failCbId: number,
args: any[],
returnValue?: any,
};
const TO_JS = 0; const TO_JS = 0;
const TO_NATIVE = 1; const TO_NATIVE = 1;
@ -43,13 +38,13 @@ const MIN_TIME_BETWEEN_FLUSHES_MS = 5;
const TRACE_TAG_REACT_APPS = 1 << 17; const TRACE_TAG_REACT_APPS = 1 << 17;
const DEBUG_INFO_LIMIT = 64; const DEBUG_INFO_LIMIT = 32;
// Work around an initialization order issue // Work around an initialization order issue
let JSTimers = null; let JSTimers = null;
class MessageQueue { class MessageQueue {
_lazyCallableModules: {[key: string]: (void) => Object}; _lazyCallableModules: {[key: string]: void => Object};
_queue: [Array<number>, Array<number>, Array<any>, number]; _queue: [Array<number>, Array<number>, Array<any>, number];
_successCallbacks: Array<?Function>; _successCallbacks: Array<?Function>;
_failureCallbacks: Array<?Function>; _failureCallbacks: Array<?Function>;
@ -78,19 +73,23 @@ class MessageQueue {
this._remoteModuleTable = {}; this._remoteModuleTable = {};
this._remoteMethodTable = {}; this._remoteMethodTable = {};
} }
(this:any).callFunctionReturnFlushedQueue = this.callFunctionReturnFlushedQueue.bind(this);
(this:any).callFunctionReturnResultAndFlushedQueue = this.callFunctionReturnResultAndFlushedQueue.bind(this);
(this:any).flushedQueue = this.flushedQueue.bind(this);
(this:any).invokeCallbackAndReturnFlushedQueue = this.invokeCallbackAndReturnFlushedQueue.bind(this);
} }
/** /**
* Public APIs * Public APIs
*/ */
static spy(spyOrToggle: boolean | ((data: SpyData) => void)) {
if (spyOrToggle === true) { static spy(spyOrToggle: boolean|(data: SpyData) => void){
if (spyOrToggle === true){
MessageQueue.prototype.__spy = info => { MessageQueue.prototype.__spy = info => {
console.log( console.log(`${info.type === TO_JS ? 'N->JS' : 'JS->N'} : ` +
`${info.type === TO_JS ? 'N->JS' : 'JS->N'} : ` + `${info.module ? (info.module + '.') : ''}${info.method}` +
`${info.module ? info.module + '.' : ''}${info.method}` + `(${JSON.stringify(info.args)})`);
`(${JSON.stringify(info.args)})`,
);
}; };
} else if (spyOrToggle === false) { } else if (spyOrToggle === false) {
MessageQueue.prototype.__spy = null; MessageQueue.prototype.__spy = null;
@ -99,40 +98,32 @@ class MessageQueue {
} }
} }
callFunctionReturnFlushedQueue = ( callFunctionReturnFlushedQueue(module: string, method: string, args: Array<any>) {
module: string,
method: string,
args: Array<any>,
) => {
this.__guard(() => { this.__guard(() => {
this.__callFunction(module, method, args); this.__callFunction(module, method, args);
}); });
return this.flushedQueue(); return this.flushedQueue();
}; }
callFunctionReturnResultAndFlushedQueue = ( callFunctionReturnResultAndFlushedQueue(module: string, method: string, args: Array<any>) {
module: string,
method: string,
args: Array<any>,
) => {
let result; let result;
this.__guard(() => { this.__guard(() => {
result = this.__callFunction(module, method, args); result = this.__callFunction(module, method, args);
}); });
return [result, this.flushedQueue()]; return [result, this.flushedQueue()];
}; }
invokeCallbackAndReturnFlushedQueue = (cbID: number, args: Array<any>) => { invokeCallbackAndReturnFlushedQueue(cbID: number, args: Array<any>) {
this.__guard(() => { this.__guard(() => {
this.__invokeCallback(cbID, args); this.__invokeCallback(cbID, args);
}); });
return this.flushedQueue(); return this.flushedQueue();
}; }
flushedQueue = () => { flushedQueue() {
this.__guard(() => { this.__guard(() => {
this.__callImmediates(); this.__callImmediates();
}); });
@ -140,7 +131,7 @@ class MessageQueue {
const queue = this._queue; const queue = this._queue;
this._queue = [[], [], [], this._callID]; this._queue = [[], [], [], this._callID];
return queue[0].length ? queue : null; return queue[0].length ? queue : null;
}; }
getEventLoopRunningTime() { getEventLoopRunningTime() {
return new Date().getTime() - this._eventLoopStartTime; return new Date().getTime() - this._eventLoopStartTime;
@ -152,7 +143,7 @@ class MessageQueue {
registerLazyCallableModule(name: string, factory: void => Object) { registerLazyCallableModule(name: string, factory: void => Object) {
let module: Object; let module: Object;
let getValue: ?(void) => Object = factory; let getValue: ?(void => Object) = factory;
this._lazyCallableModules[name] = () => { this._lazyCallableModules[name] = () => {
if (getValue) { if (getValue) {
module = getValue(); module = getValue();
@ -167,13 +158,7 @@ class MessageQueue {
return getValue ? getValue() : null; return getValue ? getValue() : null;
} }
enqueueNativeCall( enqueueNativeCall(moduleID: number, methodID: number, params: Array<any>, onFail: ?Function, onSucc: ?Function) {
moduleID: number,
methodID: number,
params: Array<any>,
onFail: ?Function,
onSucc: ?Function,
) {
if (onFail || onSucc) { if (onFail || onSucc) {
if (__DEV__) { if (__DEV__) {
this._debugInfo[this._callID] = [moduleID, methodID]; this._debugInfo[this._callID] = [moduleID, methodID];
@ -191,11 +176,7 @@ class MessageQueue {
if (__DEV__) { if (__DEV__) {
global.nativeTraceBeginAsyncFlow && global.nativeTraceBeginAsyncFlow &&
global.nativeTraceBeginAsyncFlow( global.nativeTraceBeginAsyncFlow(TRACE_TAG_REACT_APPS, 'native', this._callID);
TRACE_TAG_REACT_APPS,
'native',
this._callID,
);
} }
this._callID++; this._callID++;
@ -207,50 +188,30 @@ class MessageQueue {
JSON.stringify(params); JSON.stringify(params);
// The params object should not be mutated after being queued // The params object should not be mutated after being queued
deepFreezeAndThrowOnMutationInDev((params: any)); deepFreezeAndThrowOnMutationInDev((params:any));
} }
this._queue[PARAMS].push(params); this._queue[PARAMS].push(params);
const now = new Date().getTime(); const now = new Date().getTime();
if ( if (global.nativeFlushQueueImmediate &&
global.nativeFlushQueueImmediate && (now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS ||
(now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS || this._inCall === 0)) {
this._inCall === 0)
) {
var queue = this._queue; var queue = this._queue;
this._queue = [[], [], [], this._callID]; this._queue = [[], [], [], this._callID];
this._lastFlush = now; this._lastFlush = now;
global.nativeFlushQueueImmediate(queue); global.nativeFlushQueueImmediate(queue);
} }
Systrace.counterEvent('pending_js_to_native_queue', this._queue[0].length); Systrace.counterEvent('pending_js_to_native_queue', this._queue[0].length);
if (__DEV__ && this.__spy && isFinite(moduleID)) {
if (this.__spy) { this.__spy(
this.__spyNativeCall(moduleID, methodID, params.slice(0, -2), { { type: TO_NATIVE,
failCbId: onFail ? params[params.length - 2] : -1, module: this._remoteModuleTable[moduleID],
successCbId: onSucc ? params[params.length - 1] : -1, method: this._remoteMethodTable[moduleID][methodID],
}); args: params }
}
}
callSyncHook(moduleID: number, methodID: number, args: Array<any>) {
if (__DEV__) {
invariant(
global.nativeCallSyncHook,
'Calling synchronous methods on native ' +
'modules is not supported in Chrome.\n\n Consider providing alternative ' +
'methods to expose this method in debug mode, e.g. by exposing constants ' +
'ahead-of-time.',
); );
} else if (this.__spy) {
this.__spy({type: TO_NATIVE, module: moduleID + '', method: methodID, args: params});
} }
const returnValue = global.nativeCallSyncHook(moduleID, methodID, args);
if (this.__spy) {
this.__spyNativeCall(moduleID, methodID, args, {
isSync: true,
returnValue,
});
}
return returnValue;
} }
createDebugLookup(moduleID: number, name: string, methods: Array<string>) { createDebugLookup(moduleID: number, name: string, methods: Array<string>) {
@ -289,28 +250,18 @@ class MessageQueue {
this._eventLoopStartTime = this._lastFlush; this._eventLoopStartTime = this._lastFlush;
Systrace.beginEvent(`${module}.${method}()`); Systrace.beginEvent(`${module}.${method}()`);
if (this.__spy) { if (this.__spy) {
this.__spy({ this.__spy({ type: TO_JS, module, method, args});
type: TO_JS,
module,
method,
isSync: false,
failCbId: -1,
successCbId: -1,
args,
});
} }
const moduleMethods = this.getCallableModule(module); const moduleMethods = this.getCallableModule(module);
invariant( invariant(
!!moduleMethods, !!moduleMethods,
'Module %s is not a registered callable module (calling %s)', 'Module %s is not a registered callable module (calling %s)',
module, module, method
method,
); );
invariant( invariant(
!!moduleMethods[method], !!moduleMethods[method],
'Method %s does not exist on module %s', 'Method %s does not exist on module %s',
method, method, module
module,
); );
const result = moduleMethods[method].apply(moduleMethods, args); const result = moduleMethods[method].apply(moduleMethods, args);
Systrace.endEvent(); Systrace.endEvent();
@ -323,10 +274,7 @@ class MessageQueue {
// The rightmost bit of cbID indicates fail (0) or success (1), the other bits are the callID shifted left. // The rightmost bit of cbID indicates fail (0) or success (1), the other bits are the callID shifted left.
const callID = cbID >>> 1; const callID = cbID >>> 1;
const isSuccess = cbID & 1; const callback = (cbID & 1) ? this._successCallbacks[callID] : this._failureCallbacks[callID];
const callback = isSuccess
? this._successCallbacks[callID]
: this._failureCallbacks[callID];
if (__DEV__) { if (__DEV__) {
const debug = this._debugInfo[callID]; const debug = this._debugInfo[callID];
@ -335,38 +283,20 @@ class MessageQueue {
if (!callback) { if (!callback) {
let errorMessage = `Callback with id ${cbID}: ${module}.${method}() not found`; let errorMessage = `Callback with id ${cbID}: ${module}.${method}() not found`;
if (method) { if (method) {
errorMessage = errorMessage = `The callback ${method}() exists in module ${module}, `
`The callback ${method}() exists in module ${module}, ` + + 'but only one callback may be registered to a function in a native module.';
'but only one callback may be registered to a function in a native module.';
} }
invariant(callback, errorMessage); invariant(
callback,
errorMessage
);
} }
const profileName = debug const profileName = debug ? '<callback for ' + module + '.' + method + '>' : cbID;
? '<callback for ' + module + '.' + method + '>' if (callback && this.__spy) {
: cbID + ''; this.__spy({ type: TO_JS, module:null, method:profileName, args });
console.log(
'invokeCallback',
cbID,
debug,
callback,
module,
method,
profileName,
);
if (this.__spy) {
this.__spy({
type: TO_JS,
module: null,
method: profileName,
isSync: false,
args,
failCbId: isSuccess ? -1 : cbID,
successCbId: isSuccess ? cbID : -1,
});
} }
Systrace.beginEvent( Systrace.beginEvent(
`MessageQueue.invokeCallback(${profileName}, ${stringifySafe(args)})`, `MessageQueue.invokeCallback(${profileName}, ${stringifySafe(args)})`);
);
} }
if (!callback) { if (!callback) {
@ -380,36 +310,6 @@ class MessageQueue {
Systrace.endEvent(); Systrace.endEvent();
} }
} }
__spyNativeCall(
moduleID: number,
methodID: number,
args: any[],
params: any,
) {
const spy = this.__spy;
if (!spy) {
return;
}
let moduleName = moduleID + '';
let methodName = methodID;
if (__DEV__ && isFinite(moduleID)) {
moduleName = this._remoteModuleTable[moduleID];
methodName = this._remoteMethodTable[moduleID][methodID];
}
spy({
type: TO_NATIVE,
isSync: false,
module: moduleName,
method: methodName,
failCbId: -1,
successCbId: -1,
args,
...params,
});
}
} }
module.exports = MessageQueue; module.exports = MessageQueue;

View File

@ -82,7 +82,13 @@ function genMethod(moduleID: number, methodID: number, type: MethodType) {
}; };
} else if (type === 'sync') { } else if (type === 'sync') {
fn = function(...args: Array<any>) { fn = function(...args: Array<any>) {
return BatchedBridge.callSyncHook(moduleID, methodID, args); if (__DEV__) {
invariant(global.nativeCallSyncHook, 'Calling synchronous methods on native ' +
'modules is not supported in Chrome.\n\n Consider providing alternative ' +
'methods to expose this method in debug mode, e.g. by exposing constants ' +
'ahead-of-time.');
}
return global.nativeCallSyncHook(moduleID, methodID, args);
}; };
} else { } else {
fn = function(...args: Array<any>) { fn = function(...args: Array<any>) {

View File

@ -45,7 +45,7 @@ const BridgeSpyStallHandler = {
} }
} }
return `${info.type === TO_JS ? 'N->JS' : 'JS->N'} : ` + return `${info.type === TO_JS ? 'N->JS' : 'JS->N'} : ` +
`${info.module ? (info.module + '.') : ''}${info.method}(${JSON.stringify(args)})`; `${info.module ? (info.module + '.') : ''}${info.method}(${args})`;
}), }),
); );
}, },