Bug 1340842 - Add argument to TelemetryStopwatch that allows us to suppress warnings when finishing previously canceled stopwatches. r?Dexter draft
authorMike Conley <mconley@mozilla.com>
Fri, 17 Mar 2017 11:21:40 -0400
changeset 503027 6551a2647d3f04c9c309d802bbf83e119078ced6
parent 503026 27075b31ca80257378379e049db5fe34726cbefe
child 503028 e7ad044f1b6cfec1df15136f211db2c1e98735b5
push id50459
push usermconley@mozilla.com
push dateWed, 22 Mar 2017 17:36:55 +0000
reviewersDexter
bugs1340842
milestone55.0a1
Bug 1340842 - Add argument to TelemetryStopwatch that allows us to suppress warnings when finishing previously canceled stopwatches. r?Dexter MozReview-Commit-ID: Ck340qvxdZp
toolkit/components/telemetry/TelemetryStopwatch.jsm
toolkit/components/telemetry/docs/collection/measuring-time.rst
--- a/toolkit/components/telemetry/TelemetryStopwatch.jsm
+++ b/toolkit/components/telemetry/TelemetryStopwatch.jsm
@@ -163,38 +163,49 @@ this.TelemetryStopwatch = {
    *
    * @param {String} aHistogram - a string which must be a valid histogram name.
    *                              If an invalid name is given, the function will
    *                              throw.
    *
    * @param (Object) aObj - Optional parameter which associates the histogram
    *                        timer with the given object.
    *
+   * @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
+   *                                  warnings that normally fire when a stopwatch
+   *                                  is finished after being cancelled. Defaults
+   *                                  to false.
+   *
    * @returns {Integer} time in milliseconds or -1 if the stopwatch was not
    *                   found.
    */
-  timeElapsed(aHistogram, aObj) {
-    return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, null);
+  timeElapsed(aHistogram, aObj, aCanceledOkay) {
+    return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, null,
+                                              aCanceledOkay);
   },
 
   /**
    * Stops the timer associated with the given histogram (and object),
    * calculates the time delta between start and finish, and adds the value
    * to the histogram.
    *
    * @param {String} aHistogram - a string which must be a valid histogram name.
    *
    * @param {Object} aObj - Optional parameter which associates the histogram
    *                        timer with the given object.
    *
+   * @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
+   *                                  warnings that normally fire when a stopwatch
+   *                                  is finished after being cancelled. Defaults
+   *                                  to false.
+   *
    * @returns {Boolean} True if the timer was succesfully stopped and the data
    *                    was added to the histogram, False otherwise.
    */
-  finish(aHistogram, aObj) {
-    return TelemetryStopwatchImpl.finish(aHistogram, aObj, null);
+  finish(aHistogram, aObj, aCanceledOkay) {
+    return TelemetryStopwatchImpl.finish(aHistogram, aObj, null, aCanceledOkay);
   },
 
   /**
    * Starts a timer associated with a keyed telemetry histogram. The timer can
    * be directly associated with a histogram and its key. Similarly to
    * @see{TelemetryStopwatch.stat} the histogram and its key can be associated
    * with an object. Each key may have multiple associated objects and each
    * object can be associated with multiple keys.
@@ -246,37 +257,43 @@ this.TelemetryStopwatch = {
    *
    * @param {Object} aObj - Optional parameter. If specified, the timer
    *                        associated with this object is used to calculate
    *                        the elapsed time.
    *
    * @return {Integer} time in milliseconds or -1 if the stopwatch was not
    *                   found.
    */
-  timeElapsedKeyed(aHistogram, aKey, aObj) {
-    return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, aKey);
+  timeElapsedKeyed(aHistogram, aKey, aObj, aCanceledOkay) {
+    return TelemetryStopwatchImpl.timeElapsed(aHistogram, aObj, aKey,
+                                              aCanceledOkay);
   },
 
   /**
    * Stops the timer associated with the given keyed histogram (and object),
    * calculates the time delta between start and finish, and adds the value
    * to the keyed histogram.
    *
    * @param {String} aHistogram - a string which must be a valid histogram name.
    *
    * @param {String} aKey - a string which must be a valid histgram key.
    *
    * @param {Object} aObj - optional parameter which associates the histogram
    *                        timer with the given object.
    *
+   * @param {Boolean} aCanceledOkay - Optional parameter which will suppress any
+   *                                  warnings that normally fire when a stopwatch
+   *                                  is finished after being cancelled. Defaults
+   *                                  to false.
+   *
    * @returns {Boolean} True if the timer was succesfully stopped and the data
    *                   was added to the histogram, False otherwise.
    */
-  finishKeyed(aHistogram, aKey, aObj) {
-    return TelemetryStopwatchImpl.finish(aHistogram, aObj, aKey);
+  finishKeyed(aHistogram, aKey, aObj, aCanceledOkay) {
+    return TelemetryStopwatchImpl.finish(aHistogram, aObj, aKey, aCanceledOkay);
   }
 };
 
 this.TelemetryStopwatchImpl = {
   start(histogram, object, key) {
     if (Timers.has(histogram, object, key)) {
       Timers.delete(histogram, object, key);
       Cu.reportError(`TelemetryStopwatch: key "${histogram}" was already ` +
@@ -286,38 +303,40 @@ this.TelemetryStopwatchImpl = {
 
     return Timers.put(histogram, object, key, Components.utils.now());
   },
 
   cancel(histogram, object, key) {
     return Timers.delete(histogram, object, key);
   },
 
-  timeElapsed(histogram, object, key) {
+  timeElapsed(histogram, object, key, aCanceledOkay) {
     let startTime = Timers.get(histogram, object, key);
     if (startTime === null) {
-      Cu.reportError("TelemetryStopwatch: requesting elapsed time for " +
-                     `nonexisting stopwatch. Histogram: "${histogram}", ` +
-                     `key: "${key}"`);
+      if (!aCanceledOkay) {
+        Cu.reportError("TelemetryStopwatch: requesting elapsed time for " +
+                       `nonexisting stopwatch. Histogram: "${histogram}", ` +
+                       `key: "${key}"`);
+      }
       return -1;
     }
 
     try {
       let delta = Components.utils.now() - startTime
       return Math.round(delta);
     } catch (e) {
       Cu.reportError("TelemetryStopwatch: failed to calculate elapsed time " +
                      `for Histogram: "${histogram}", key: "${key}", ` +
                      `exception: ${Log.exceptionStr(e)}`);
       return -1;
     }
   },
 
-  finish(histogram, object, key) {
-    let delta = this.timeElapsed(histogram, object, key);
+  finish(histogram, object, key, aCanceledOkay) {
+    let delta = this.timeElapsed(histogram, object, key, aCanceledOkay);
     if (delta == -1) {
       return false;
     }
 
     try {
       if (key) {
         Telemetry.getKeyedHistogramById(histogram).add(key, delta);
       } else {
--- a/toolkit/components/telemetry/docs/collection/measuring-time.rst
+++ b/toolkit/components/telemetry/docs/collection/measuring-time.rst
@@ -39,16 +39,29 @@ Example:
     if (failedToOpenFile) {
       // Cancel this if the operation failed early etc.
       TelemetryStopwatch.cancel("SAMPLE_FILE_LOAD_TIME_MS");
       return;
     }
     // ... do more work.
     TelemetryStopwatch.finish("SAMPLE_FILE_LOAD_TIME_MS");
 
+    // Periodically, it's necessary to attempt to finish a
+    // TelemetryStopwatch that's already been canceled or
+    // finished. Normally, that throws a warning to the
+    // console. If the TelemetryStopwatch being possibly
+    // cancelled or finished is expected behaviour, the
+    // warning can be suppressed by passing the optional
+    // aCanceledOkay argument.
+
+    // ... suppress warning on a previously finished
+    // TelemetryStopwatch
+    TelemetryStopwatch.finish("SAMPLE_FILE_LOAD_TIME_MS", null,
+                              true /* aCanceledOkay */);
+
 From C++
 ========
 
 API:
 
 .. code-block:: cpp
 
     // This helper class is the preferred way to record elapsed time.