Bug1358038 : Add 'Race Cache With Network' status to netmonitor. r?Honza draft
authormayank.raj <mayank9856@gmail.com>
Mon, 14 May 2018 04:06:27 +0530
changeset 794589 fd63f75fc23a2bb254c4998948196a72897b9939
parent 794572 a7461494a7a0bb3d80c1449c1d5d484d8b568d98
push id109729
push userbmo:mayank9856@gmail.com
push dateSun, 13 May 2018 22:37:15 +0000
reviewersHonza
bugs1358038
milestone62.0a1
Bug1358038 : Add 'Race Cache With Network' status to netmonitor. r?Honza MozReview-Commit-ID: JnbrltaqA9L
.gitignore
devtools/client/netmonitor/src/components/RequestListColumnTransferredSize.js
devtools/client/netmonitor/src/components/RequestListItem.js
devtools/client/netmonitor/src/connector/firefox-data-provider.js
devtools/server/actors/webconsole.js
devtools/shared/webconsole/client.js
devtools/shared/webconsole/network-monitor.js
--- a/.gitignore
+++ b/.gitignore
@@ -56,17 +56,17 @@ parser/html/java/htmlparser/
 parser/html/java/javaparser/
 
 # Ignore the files and directory that Eclipse IDE creates
 .project
 .cproject
 .settings/
 
 # Ignore the files and directory that JetBrains IDEs create.
-/.idea/
+/*/.idea/
 *.iml
 # Android Monitor in Android Studio creates a captures/ directory.
 /captures/
 
 # Gradle cache.
 /.gradle/
 
 # Local Gradle configuration properties.
--- a/devtools/client/netmonitor/src/components/RequestListColumnTransferredSize.js
+++ b/devtools/client/netmonitor/src/components/RequestListColumnTransferredSize.js
@@ -28,29 +28,36 @@ class RequestListColumnTransferredSize e
     };
   }
 
   shouldComponentUpdate(nextProps) {
     return !propertiesEqual(UPDATED_TRANSFERRED_PROPS, this.props.item, nextProps.item);
   }
 
   render() {
-    let { fromCache, fromServiceWorker, status, transferredSize } = this.props.item;
+    let {
+      fromCache, fromServiceWorker, status,
+      transferredSize, isRacing
+    } = this.props.item;
     let text;
 
     if (fromCache || status === "304") {
       text = SIZE_CACHED;
     } else if (fromServiceWorker) {
       text = SIZE_SERVICE_WORKER;
     } else if (typeof transferredSize == "number") {
       text = getFormattedSize(transferredSize);
     } else if (transferredSize === null) {
       text = SIZE_UNAVAILABLE;
     }
 
+    if (isRacing) {
+      text += " (raced)";
+    }
+
     return (
       div({ className: "requests-list-column requests-list-transferred", title: text },
         text
       )
     );
   }
 }
 
--- a/devtools/client/netmonitor/src/components/RequestListItem.js
+++ b/devtools/client/netmonitor/src/components/RequestListItem.js
@@ -91,16 +91,17 @@ loader.lazyGetter(this, "RequestListColu
  */
 const UPDATED_REQ_ITEM_PROPS = [
   "mimeType",
   "eventTimings",
   "securityState",
   "status",
   "statusText",
   "fromCache",
+  "isRacing",
   "fromServiceWorker",
   "method",
   "url",
   "remoteAddress",
   "cause",
   "contentSize",
   "transferredSize",
   "startedMillis",
@@ -127,16 +128,17 @@ class RequestListItem extends Component 
     return {
       connector: PropTypes.object.isRequired,
       columns: PropTypes.object.isRequired,
       item: PropTypes.object.isRequired,
       index: PropTypes.number.isRequired,
       isSelected: PropTypes.bool.isRequired,
       firstRequestStartedMillis: PropTypes.number.isRequired,
       fromCache: PropTypes.bool,
+      isRacing: PropTypes.bool,
       onCauseBadgeMouseDown: PropTypes.func.isRequired,
       onContextMenu: PropTypes.func.isRequired,
       onFocusedNodeChange: PropTypes.func,
       onMouseDown: PropTypes.func.isRequired,
       onSecurityIconMouseDown: PropTypes.func.isRequired,
       onWaterfallMouseDown: PropTypes.func.isRequired,
       requestFilterTypes: PropTypes.object.isRequired,
       waterfallWidth: PropTypes.number,
--- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js
+++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js
@@ -65,16 +65,17 @@ class FirefoxDataProvider {
   async addRequest(id, data) {
     let {
       method,
       url,
       isXHR,
       cause,
       startedDateTime,
       fromCache,
+      isRacing,
       fromServiceWorker,
     } = data;
 
     if (this.actionsEnabled && this.actions.addRequest) {
       await this.actions.addRequest(id, {
         // Convert the received date/time string to a unix timestamp.
         startedMillis: Date.parse(startedDateTime),
         method,
@@ -83,16 +84,17 @@ class FirefoxDataProvider {
         cause,
 
         // Compatibility code to support Firefox 58 and earlier that always
         // send stack-trace immediately on networkEvent message.
         // FF59+ supports fetching the traces lazily via requestData.
         stacktrace: cause.stacktrace,
 
         fromCache,
+        isRacing,
         fromServiceWorker,
       }, true);
     }
 
     this.emit(EVENTS.REQUEST_ADDED, id);
   }
 
   /**
@@ -311,28 +313,30 @@ class FirefoxDataProvider {
    *
    * @param {object} networkInfo network request information
    */
   async onNetworkEvent(networkInfo) {
     let {
       actor,
       cause,
       fromCache,
+      isRacing,
       fromServiceWorker,
       isXHR,
       request: {
         method,
         url,
       },
       startedDateTime,
     } = networkInfo;
 
     await this.addRequest(actor, {
       cause,
       fromCache,
+      isRacing,
       fromServiceWorker,
       isXHR,
       method,
       startedDateTime,
       url,
     });
 
     this.emit(EVENTS.NETWORK_EVENT, actor);
@@ -375,16 +379,19 @@ class FirefoxDataProvider {
         // Total time doesn't have to be always set e.g. net provider enhancer
         // in Console panel is using this method to fetch data when network log
         // is expanded. So, make sure to not push undefined into the payload queue
         // (it could overwrite an existing value).
         if (typeof networkInfo.totalTime !== "undefined") {
           this.pushRequestToQueue(actor, { totalTime: networkInfo.totalTime });
         }
         break;
+      case "racingInfo":
+        this.pushRequestToQueue(actor, { isRacing: networkInfo.isRacing });
+        break;
     }
 
     // This available field helps knowing when/if updateType property is arrived
     // and can be requested via `requestData`
     this.pushRequestToQueue(actor, { [`${updateType}Available`]: true });
 
     this.onPayloadDataReceived(actor);
 
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -2269,16 +2269,33 @@ NetworkEventActor.prototype =
       updateType: "responseStart",
       response: info
     };
 
     this.conn.send(packet);
   },
 
   /**
+   * Add connection Racing information.
+   *
+   * @param object info
+   *        The object containing Racing Information
+   */
+  addRacingInfo: function(info) {
+    let packet = {
+      from: this.actorID,
+      type: "networkEventUpdate",
+      updateType: "racingInfo",
+      isRacing: info.isRacing
+    };
+
+    this.conn.send(packet);
+  },
+
+  /**
    * Add connection security information.
    *
    * @param object info
    *        The object containing security information.
    */
   addSecurityInfo: function(info) {
     this._securityInfo = info;
 
--- a/devtools/shared/webconsole/client.js
+++ b/devtools/shared/webconsole/client.js
@@ -105,17 +105,18 @@ WebConsoleClient.prototype = {
         isXHR: actor.isXHR,
         cause: actor.cause,
         response: {},
         timings: {},
         // track the list of network event updates
         updates: [],
         private: actor.private,
         fromCache: actor.fromCache,
-        fromServiceWorker: actor.fromServiceWorker
+        fromServiceWorker: actor.fromServiceWorker,
+        isRacing: actor.isRacing
       };
       this._networkRequests.set(actor.actor, networkInfo);
 
       this.emit("networkEvent", networkInfo);
     }
   },
 
   /**
@@ -165,16 +166,19 @@ WebConsoleClient.prototype = {
         networkInfo.totalTime = packet.totalTime;
         break;
       case "securityInfo":
         networkInfo.securityInfo = packet.state;
         break;
       case "responseCache":
         networkInfo.response.responseCache = packet.responseCache;
         break;
+      case "racingInfo":
+        networkInfo.isRacing = packet.isRacing;
+        break;
     }
 
     this.emit("networkEventUpdate", {
       packet: packet,
       networkInfo
     });
   },
 
--- a/devtools/shared/webconsole/network-monitor.js
+++ b/devtools/shared/webconsole/network-monitor.js
@@ -431,16 +431,17 @@ NetworkResponseListener.prototype = {
    */
   onStartRequest: function(request) {
     // Converter will call this again, we should just ignore that.
     if (this.request) {
       return;
     }
 
     this.request = request;
+    this._fetchRaceInformation();
     this._getSecurityInfo();
     this._findOpenResponse();
     // We need to track the offset for the onDataAvailable calls where
     // we pass the data from our pipe to the converter.
     this.offset = 0;
 
     let channel = this.request;
 
@@ -515,16 +516,32 @@ NetworkResponseListener.prototype = {
     // security info for the https request after redirect.
     let secinfo = this.httpActivity.channel.securityInfo;
     let info = NetworkHelper.parseSecurityInfo(secinfo, this.httpActivity);
 
     this.httpActivity.owner.addSecurityInfo(info);
   }),
 
   /**
+   * Fetches Race information
+   * @private
+   */
+  _fetchRaceInformation: function() {
+    let racingInfo = {
+      "isRacing": false
+    };
+
+    if (this.httpActivity.channel instanceof Ci.nsIRaceCacheWithNetwork) {
+      racingInfo.isRacing = true;
+    }
+
+    this.httpActivity.owner.addRacingInfo(racingInfo);
+  },
+
+  /**
    * Fetches cache information from CacheEntry
    * @private
    */
   _fetchCacheInformation: function() {
     let httpActivity = this.httpActivity;
     CacheEntry.getCacheEntry(this.request, (descriptor) => {
       httpActivity.owner.addResponseCache({
         responseCache: descriptor
@@ -1913,17 +1930,17 @@ NetworkEventActorProxy.prototype = {
   }),
 };
 
 (function() {
   // Listeners for new network event data coming from the NetworkMonitor.
   let methods = ["addRequestHeaders", "addRequestCookies", "addRequestPostData",
                  "addResponseStart", "addSecurityInfo", "addResponseHeaders",
                  "addResponseCookies", "addResponseContent", "addResponseCache",
-                 "addEventTimings"];
+                 "addRacingInfo", "addEventTimings"];
   let factory = NetworkEventActorProxy.methodFactory;
   for (let method of methods) {
     NetworkEventActorProxy.prototype[method] = factory(method);
   }
 })();
 
 /**
  * This is triggered by the child calling `setupInParent` when the child's network monitor