Make MessageQueue to emit "SPY" events in a way that can be extensible #9160

Closed
wants to merge 6 commits into
from

Projects

None yet

4 participants

@jondot
Contributor
jondot commented Aug 2, 2016

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
Aggregating and Charting Events with Bar

This removes the hardcoded SPY_MODE flag and instead uses a function that can be injected from outside world.

MessageQueue.spy((info)=>console.log("event!", info)

It also creates a structured descriptor for an event, so in the above example, console.log will accept the following object shape:

{
   type: integer, (0:TO_JS, 1:TO_NATIVE)
   module:string,
   method:string,
   args:[object]
}

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.

jondot added some commits Jul 27, 2016
@jondot jondot Add capability for MessageQueue to emit "SPY" events
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.
6797329
@jondot jondot make compatible with rn-snoopy
d4c26c5
@ghost
ghost commented Aug 2, 2016

By analyzing the blame information on this pull request, we identified @javache and @lexs to be potential reviewers.

@eslint-bot eslint-bot commented on an outdated diff Aug 2, 2016
Libraries/Utilities/MessageQueue.js
@@ -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
@eslint-bot
eslint-bot Aug 2, 2016

semi: Missing semicolon.

@eslint-bot eslint-bot commented on an outdated diff Aug 2, 2016
Libraries/Utilities/MessageQueue.js
@@ -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
@eslint-bot
eslint-bot Aug 2, 2016

semi: Missing semicolon.

@jondot jondot add semicolons
71b4d40
@facebook-github-bot

@jondot updated the pull request.

@ghost
ghost commented Aug 2, 2016

@jondot updated the pull request.

@ghost ghost added the CLA Signed label Aug 2, 2016
@javache javache commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -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] + '.' +
@javache
javache Aug 3, 2016 Member

Can you keep the original console.log feature around somewhere?

@jondot
jondot Aug 3, 2016 edited Contributor

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?

@javache
javache Aug 3, 2016 Member

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?

@jondot
jondot Aug 3, 2016 Contributor

sounds even better, thanks for the idea!

@jondot
jondot Aug 3, 2016 Contributor

Changes are in!

@jondot jondot add default spy, better spy() interface. /cc @javache
0ab77fe
@facebook-github-bot

@jondot updated the pull request.

@javache javache and 1 other commented on an outdated diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -26,9 +26,11 @@ 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;
+const defaultSpy = (info)=>console.log(`${info.type == TO_JS ? 'N->JS' : 'JS->N'} : ${info.module ? (info.module+'.') : ''}${info.method}(${JSON.stringify(info.args)})`);
@javache
javache Aug 3, 2016 Member

Can you split this over multiple lines? Since it's also only used in one spot, I'd just define it inline in spy

@jondot
jondot Aug 3, 2016 Contributor

yup!

@javache javache and 1 other commented on an outdated diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +92,17 @@ class MessageQueue {
/**
* Public APIs
*/
+
+ static spy(spyOrToggle){
+ if(spyOrToggle === true){
@javache
javache Aug 3, 2016 Member

style nit: if (spyOrToggle === true)

@jondot
jondot Aug 3, 2016 Contributor

👍

@javache javache and 1 other commented on an outdated diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -448,4 +465,6 @@ function lazyProperty(target: Object, name: string, f: () => any) {
});
}
+
@javache
javache Aug 3, 2016 Member

Remove these

@jondot
jondot Aug 3, 2016 Contributor

👍

@eslint-bot eslint-bot commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +92,17 @@ class MessageQueue {
@eslint-bot
eslint-bot Aug 3, 2016

keyword-spacing: Expected space(s) after "if".

@eslint-bot eslint-bot commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +92,17 @@ class MessageQueue {
/**
* Public APIs
@eslint-bot
eslint-bot Aug 3, 2016

keyword-spacing: Expected space(s) after "if".

@eslint-bot eslint-bot commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -26,9 +26,11 @@ const METHOD_IDS = 1;
const PARAMS = 2;
const MIN_TIME_BETWEEN_FLUSHES_MS = 5;
-const TRACE_TAG_REACT_APPS = 1 << 17;
@eslint-bot
eslint-bot Aug 3, 2016

eqeqeq: Expected '===' and instead saw '=='.

@eslint-bot
eslint-bot Aug 3, 2016

space-infix-ops: Infix operators must be spaced.

@jondot jondot inline log, cosmetics
8f98429
@ghost
ghost commented Aug 3, 2016

@jondot updated the pull request.

@ghost ghost added the CLA Signed label Aug 3, 2016
@eslint-bot eslint-bot commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +91,19 @@ class MessageQueue {
/**
* Public APIs
@eslint-bot
eslint-bot Aug 3, 2016

eqeqeq: Expected '===' and instead saw '=='.

@eslint-bot eslint-bot commented on the diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +91,19 @@ class MessageQueue {
/**
* Public APIs
*/
@eslint-bot
eslint-bot Aug 3, 2016

space-infix-ops: Infix operators must be spaced.

@javache javache and 1 other commented on an outdated diff Aug 3, 2016
Libraries/Utilities/MessageQueue.js
@@ -90,6 +91,19 @@ class MessageQueue {
/**
* Public APIs
*/
+
+ static spy(spyOrToggle){
+ if (spyOrToggle === true){
+ MessageQueue.prototype.__spy = (info)=>console.log(`${info.type == TO_JS ? 'N->JS' : 'JS->N'} : ` +
@javache
javache Aug 3, 2016 Member

Can you split this over multiple lines?

MessageQueue.prototype.__spy = (info) => {
  console.log(...)
};
@jondot
jondot Aug 4, 2016 Contributor

Yup, thanks!

@jondot jondot some more cosmetics
fbcf3c1
@facebook-github-bot

@jondot updated the pull request.

@eslint-bot eslint-bot commented on the diff Aug 4, 2016
Libraries/Utilities/MessageQueue.js
-const SPY_MODE = false;
+const TRACE_TAG_REACT_APPS = 1 << 17;
const MethodTypes = keyMirror({
@eslint-bot
eslint-bot Aug 4, 2016

semi: Missing semicolon.

@eslint-bot eslint-bot commented on the diff Aug 4, 2016
Libraries/Utilities/MessageQueue.js
-const SPY_MODE = false;
+const TRACE_TAG_REACT_APPS = 1 << 17;
@eslint-bot
eslint-bot Aug 4, 2016

space-infix-ops: Infix operators must be spaced.

@eslint-bot eslint-bot commented on the diff Aug 4, 2016
Libraries/Utilities/MessageQueue.js
-const SPY_MODE = false;
@eslint-bot
eslint-bot Aug 4, 2016

eqeqeq: Expected '===' and instead saw '=='.

@ghost ghost added the CLA Signed label Aug 4, 2016
@javache
Member
javache commented Aug 4, 2016

@facebook-github-bot shipit

@ghost
ghost commented Aug 4, 2016

Thanks for importing.

@ghost ghost added the CLA Signed label Aug 4, 2016
@ghost Unknown added a commit that closed this pull request Aug 4, 2016
@jondot jondot + Facebook Github Bot 7 Make MessageQueue to emit "SPY" events in a way that can be extensible
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 #9160

Differential Revision: D3669053

Pulled By: javache

fbshipit-source-id: 3e4462aa77fc8514d2ea4f15430f7bec57b583a4
77e48f1
@ghost ghost closed this in 77e48f1 Aug 4, 2016
@mpretty-cyro mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016
@jondot jondot + Morgan Pretty Make MessageQueue to emit "SPY" events in a way that can be extensible
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
af371b3
@jondot jondot added a commit to jondot/rn-snoopy that referenced this pull request Sep 26, 2016
@jondot jondot Update Snoopy to use the now official spy integration
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.
b03c382
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment