-
Notifications
You must be signed in to change notification settings - Fork 24.5k
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
Make MessageQueue to emit "SPY" events in a way that can be extensible #9160
Conversation
in a way that can be extensible. After this change, we can wire a "spy" into a queue that will expose the events in different and interesting ways. This removes the hardcoded `SPY_MODE` flag and instead uses a function that can be injected from outside. This change will enable a tool like Snoopy to exist, without its internal monkeypatching of MessageQueue: https://github.com/jondot/rn-snoopy This was a low-hanging-fruit waiting to be picked. And now, we have deeper and more elaborate introspection at the React Native bridge traffic, empowering optimization and debugging scenarios alike.
@@ -26,9 +26,10 @@ const METHOD_IDS = 1; | |||
const PARAMS = 2; | |||
const MIN_TIME_BETWEEN_FLUSHES_MS = 5; | |||
|
|||
const TRACE_TAG_REACT_APPS = 1 << 17; | |||
const TO_NATIVE = 1 | |||
const TO_JS = 0 |
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.
semi: Missing semicolon.
@jondot updated the pull request. |
1 similar comment
@jondot updated the pull request. |
@@ -182,18 +188,22 @@ class MessageQueue { | |||
this._lastFlush = now; | |||
} | |||
Systrace.counterEvent('pending_js_to_native_queue', this._queue[0].length); | |||
if (__DEV__ && SPY_MODE && isFinite(module)) { | |||
console.log('JS->N : ' + this._remoteModuleTable[module] + '.' + |
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.
Can you keep the original console.log feature around somewhere?
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.
Yes!
I'm thinking perhaps a default 'spy' implementation, that you can use and is built-in.
Something like I did with this and this.
The ergonomics would look like this:
MessageQueue.spy()
sets the default logging strategy in place.
Then clearing a spy, disables tracing, and would have to be done like so
MessageQueue.spy(null)
WDYT?
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.
Maybe MessageQueue.spy(true) to turn on the default function, MessageQueue.spy(fn) to provide a custom function and MessageQueue.spy(false) to turn it off?
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.
sounds even better, thanks for the idea!
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.
Changes are in!
@jondot updated the pull request. |
const TRACE_TAG_REACT_APPS = 1 << 17; | ||
const TO_NATIVE = 1; | ||
const TO_JS = 0; | ||
const defaultSpy = (info)=>console.log(`${info.type == TO_JS ? 'N->JS' : 'JS->N'} : ${info.module ? (info.module+'.') : ''}${info.method}(${JSON.stringify(info.args)})`); |
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.
Can you split this over multiple lines? Since it's also only used in one spot, I'd just define it inline in spy
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.
yup!
@@ -90,6 +92,17 @@ class MessageQueue { |
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.
keyword-spacing: Expected space(s) after "if".
@jondot updated the pull request. |
@@ -90,6 +91,19 @@ class MessageQueue { | |||
/** | |||
* Public APIs |
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.
eqeqeq: Expected '===' and instead saw '=='.
@jondot updated the pull request. |
|
||
const SPY_MODE = false; | ||
const TRACE_TAG_REACT_APPS = 1 << 17; | ||
|
||
const MethodTypes = keyMirror({ |
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.
semi: Missing semicolon.
|
||
const SPY_MODE = false; | ||
const TRACE_TAG_REACT_APPS = 1 << 17; |
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.
space-infix-ops: Infix operators must be spaced.
@facebook-github-bot shipit |
Thanks for importing. |
Summary: This PR adds a capability for MessageQueue to emit "SPY" events in a way that can be extensible, to later allow for a tooling ecosystem to grow, one example is the existing [Snoopy](https://github.com/jondot/rn-snoopy) tool that is, for now, forced to work with monkeypatches, and after this PR will be able to use a "formal" way to trace queue events. After this change, we can wire a "spy" into a queue that will expose the events in different and interesting ways, see below (done with Snoopy): <img src="https://github.com/jondot/rn-snoopy/blob/master/media/snoopy.gif?raw=true" alt="Aggregating and Charting Events with Bar" width="400px"/> <img src="https://github.com/jondot/rn-snoopy/blob/master/media/snoopy-filter.gif?raw=true" alt="Aggregating and Charting Events with Bar" width="400px"/> This removes the hardcoded `SPY_MODE` flag and instead uses a function that can be injected from outside world. ```javascript MessageQueue.spy((info)=>console.log("event!", info) ``` It also creates Closes facebook#9160 Differential Revision: D3669053 Pulled By: javache fbshipit-source-id: 3e4462aa77fc8514d2ea4f15430f7bec57b583a4
see: facebook/react-native#9160 Bump version so that it's visibly clear this is React Native 0.33 and up (v1.33.0) Update example and make notes of this in README.
This PR adds a capability for MessageQueue to emit "SPY" events in a way that can be extensible, to later allow for a tooling ecosystem to grow, one example is the existing Snoopy tool that is, for now, forced to work with monkeypatches, and after this PR will be able to use a "formal" way to trace queue events.
After this change, we can wire a "spy" into a queue that will expose the events in different and interesting ways, see below (done with Snoopy):
![Aggregating and Charting Events with Bar](https://github.com/jondot/rn-snoopy/blob/master/media/snoopy.gif?raw=true)
![Aggregating and Charting Events with Bar](https://github.com/jondot/rn-snoopy/blob/master/media/snoopy-filter.gif?raw=true)
This removes the hardcoded
SPY_MODE
flag and instead uses a function that can be injected from outside world.It also creates a structured descriptor for an event, so in the above example,
console.log
will accept the following object shape:Once a spy exists (and we're in
__DEV__
mode), the queue will start using it.In terms of core changes - I feel this was a low-hanging-fruit, small enough to pick.