Changed the interface used to send metrics to a dashboard application. The
change allows the notifier implementation to do something at the start of an
event.

Review at http://gwt-code-reviews.appspot.com/1499811


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10649 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
index fa5adf0..63ad7ea 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
@@ -381,7 +381,7 @@
    * @throws IOException
    */
   public void shutdown() throws IOException {
-    getDashboardNotifier().devModeSessionEnded(devModeSession);
+    getDashboardNotifier().devModeSessionEnd(devModeSession);
     QuitMessage.send(this);
   }
 
@@ -664,7 +664,7 @@
   private void createDevModeSession() {
     devModeSession = new DevModeSession(moduleName, userAgent);
     DevModeSession.setSessionForCurrentThread(devModeSession);
-    getDashboardNotifier().devModeSession(devModeSession);
+    getDashboardNotifier().devModeSessionBegin(devModeSession);
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/util/log/dashboard/DashboardNotifier.java b/dev/core/src/com/google/gwt/dev/util/log/dashboard/DashboardNotifier.java
index a4eaebe..8a2c366 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/dashboard/DashboardNotifier.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/dashboard/DashboardNotifier.java
@@ -23,32 +23,28 @@
  * information from GWT runtime and compiler instrumentation.
  */
 public interface DashboardNotifier {
-  // First: Compiler related entry points
-
-  // TODO(jhumphries) Add interface methods for collecting data from the
-  // compiler
-
-  // Second: Devmode related entry points
 
   /**
-   * Notifies the dashboard of a top-level event.
+   * Notifies the dashboard of a new top-level event starting.
    */
-  void devModeEvent(DevModeSession session, String eventType, long startTimeNanos,
+  void devModeEventBegin();
+
+  /**
+   * Notifies the dashboard of a top-level event ending.
+   */
+  void devModeEventEnd(DevModeSession session, String eventType, long startTimeNanos,
       long durationNanos);
 
   /**
    * Notifies the dashboard of a new session starting.
    */
-  void devModeSession(DevModeSession session);
+  void devModeSessionBegin(DevModeSession session);
 
   /**
    * Notifies the dashboard of a session ending.
    */
-  void devModeSessionEnded(DevModeSession session);
+  void devModeSessionEnd(DevModeSession session);
 
-  // Third: Test related entry points
-
-  // TODO(jhumphries) Add interface methods for collecting data from automated
-  // tests
+  // TODO(jhumphries) Add instrumentation for compiles and GWT tests, too
 
 }
diff --git a/dev/core/src/com/google/gwt/dev/util/log/dashboard/NoOpDashboardNotifier.java b/dev/core/src/com/google/gwt/dev/util/log/dashboard/NoOpDashboardNotifier.java
index e6a8a30..2dfa865 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/dashboard/NoOpDashboardNotifier.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/dashboard/NoOpDashboardNotifier.java
@@ -24,18 +24,23 @@
 public class NoOpDashboardNotifier implements DashboardNotifier {
 
   @Override
-  public void devModeEvent(DevModeSession sesion, String eventType, long startTimeNanos,
+  public void devModeEventBegin() {
+    // do nothing
+  }
+
+  @Override
+  public void devModeEventEnd(DevModeSession sesion, String eventType, long startTimeNanos,
       long durationNanos) {
     // do nothing
   }
 
   @Override
-  public void devModeSession(DevModeSession session) {
+  public void devModeSessionBegin(DevModeSession session) {
     // do nothing
   }
 
   @Override
-  public void devModeSessionEnded(DevModeSession session) {
+  public void devModeSessionEnd(DevModeSession session) {
     // do nothing
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
index d415527..0866fcf 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/SpeedTracerLogger.java
@@ -38,6 +38,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Logs performance metrics for internal development purposes. The output is
@@ -54,6 +56,8 @@
  */
 public final class SpeedTracerLogger {
   
+  private static final Logger log = Logger.getLogger(SpeedTracerLogger.class.getName());
+  
   // Log file name (logging is enabled if this is non-null)
   private static final String logFile = 
     System.getProperty("gwt.speedtracerlog");
@@ -548,9 +552,8 @@
         writer.close();
       } catch (InterruptedException ignored) {
       } catch (IOException e) {
-        System.err.println("Unable to write to gwt.speedtracerlog '"
-            + (fileName == null ? "" : fileName) + "'");
-        e.printStackTrace();
+        log.log(Level.SEVERE, "Unable to write to gwt.speedtracerlog '"
+            + (fileName == null ? "" : fileName) + "'", e);
       } finally {
         shutDownLatch.countDown();
       }
@@ -862,7 +865,7 @@
         eventsToWrite.add(currentEvent);
       }
 
-      DashboardNotifierFactory.getNotifier().devModeEvent(currentEvent.getDevModeSession(),
+      DashboardNotifierFactory.getNotifier().devModeEventEnd(currentEvent.getDevModeSession(),
           currentEvent.getType().getName(), currentEvent.getElapsedStartTimeNanos(),
           currentEvent.getElapsedDurationNanos());
     }
@@ -902,6 +905,7 @@
     if (!threadPendingEvents.isEmpty()) {
       parent = threadPendingEvents.peek();
     } else {
+      DashboardNotifierFactory.getNotifier().devModeEventBegin();
       if (logThreadCpuTime) {
         // reset the thread CPU time base for top-level events (so events can be
         // properly sequenced chronologically)
@@ -938,9 +942,7 @@
         writer = new BufferedWriter(new FileWriter(logFile));
         return openLogWriter(writer, logFile);
       } catch (IOException e) {
-        System.err.println(
-            "Unable to open gwt.speedtracerlog '" + logFile + "'");
-        e.printStackTrace();
+        log.log(Level.SEVERE, "Unable to open gwt.speedtracerlog '" + logFile + "'", e);
       }
     }
     return null;
@@ -962,9 +964,8 @@
                 + "<div style=\"display: none\" id=\"traceData\" version=\"0.17\">\n");
       }
     } catch (IOException e) {
-      System.err.println("Unable to write to gwt.speedtracerlog '"
-          + (fileName == null ? "" : fileName) + "'");
-      e.printStackTrace();
+      log.log(Level.SEVERE, "Unable to write to gwt.speedtracerlog '"
+          + (fileName == null ? "" : fileName) + "'", e);
       return null;
     }
 
diff --git a/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java b/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
index f43552f..c8cd8d6 100644
--- a/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
@@ -199,24 +199,29 @@
     boolean ended;
 
     @Override
-    public void devModeEvent(DevModeSession session, String eventType, long startTimeNanos,
-        long durationNanos) {
-      fail("BrowserChannelServer should not be calling DashboardNotifier.devModeEvent()");
+    public void devModeEventBegin() {
+      fail("BrowserChannelServer should not be calling DashboardNotifier.devModeEventBegin()");
     }
 
     @Override
-    public void devModeSession(DevModeSession session) {
+    public void devModeEventEnd(DevModeSession session, String eventType, long startTimeNanos,
+        long durationNanos) {
+      fail("BrowserChannelServer should not be calling DashboardNotifier.devModeEventEnd()");
+    }
+
+    @Override
+    public void devModeSessionBegin(DevModeSession session) {
       currentSession = session;
-      assertFalse("DashboardNotifier.devModeSession() called more than once", started);
+      assertFalse("DashboardNotifier.devModeSessionBegin() called more than once", started);
       started = true;
     }
 
     @Override
-    public void devModeSessionEnded(DevModeSession session) {
-      assertTrue("DashboardNotifier.devModeSessionEnded() without prior call to "
-          + "DashboardNotifier.devModeSession()", started);
-      assertFalse("DashboardNotifier.devModeSessionEnded() called more than once", ended);
-      assertEquals("Wrong session passed to DashboardNotifier.devModeSessionEnded()",
+    public void devModeSessionEnd(DevModeSession session) {
+      assertTrue("DashboardNotifier.devModeSessionEnd() without prior call to "
+          + "DashboardNotifier.devModeSessionBegin()", started);
+      assertFalse("DashboardNotifier.devModeSessionEnd() called more than once", ended);
+      assertEquals("Wrong session passed to DashboardNotifier.devModeSessionEnd()",
           currentSession, session);
       ended = true;
     }
diff --git a/dev/core/test/com/google/gwt/dev/util/log/dashboard/DashboardNotifierFactoryTest.java b/dev/core/test/com/google/gwt/dev/util/log/dashboard/DashboardNotifierFactoryTest.java
index 6765ea0..e9cefb3 100644
--- a/dev/core/test/com/google/gwt/dev/util/log/dashboard/DashboardNotifierFactoryTest.java
+++ b/dev/core/test/com/google/gwt/dev/util/log/dashboard/DashboardNotifierFactoryTest.java
@@ -28,18 +28,23 @@
     // create test notifier instance
     DashboardNotifier obj = new DashboardNotifier() {
       @Override
-      public void devModeEvent(DevModeSession session, String eventType, long startTimeNanos,
+      public void devModeEventBegin() {
+        // no need to do anything
+      }
+
+      @Override
+      public void devModeEventEnd(DevModeSession session, String eventType, long startTimeNanos,
           long durationNanos) {
         // no need to do anything
       }
 
       @Override
-      public void devModeSession(DevModeSession session) {
+      public void devModeSessionBegin(DevModeSession session) {
         // no need to do anything
       }
 
       @Override
-      public void devModeSessionEnded(DevModeSession session) {
+      public void devModeSessionEnd(DevModeSession session) {
         // no need to do anything
       }
     };
diff --git a/dev/core/test/com/google/gwt/dev/util/log/dashboard/SpeedTracerLoggerTestMockNotifier.java b/dev/core/test/com/google/gwt/dev/util/log/dashboard/SpeedTracerLoggerTestMockNotifier.java
index e6cd463..354366a 100644
--- a/dev/core/test/com/google/gwt/dev/util/log/dashboard/SpeedTracerLoggerTestMockNotifier.java
+++ b/dev/core/test/com/google/gwt/dev/util/log/dashboard/SpeedTracerLoggerTestMockNotifier.java
@@ -92,29 +92,49 @@
    * Keeps track of calls to {@code devModeEvent()}.
    */
   private LinkedList<DevModeEvent> eventSeq = new LinkedList<DevModeEvent>();
+  private boolean started;
 
   @Override
-  public void devModeEvent(DevModeSession session, String eventType, long startTimeNanos,
+  public void devModeEventBegin() {
+    Assert.assertFalse("DashboardNotifier.devModeEventBegin() called more than once "
+        + "before call DashboardNotifier.devModeEventEnd()", started);
+    started = true;
+  }
+  
+  @Override
+  public void devModeEventEnd(DevModeSession session, String eventType, long startTimeNanos,
       long durationNanos) {
+    Assert.assertTrue("DashboardNotifier.devModeEventEnd() without prior call to "
+        + "DashboardNotifier.devModeEventBegin()", started);
+    started = false;
     DevModeEvent e = new DevModeEvent(session, eventType, startTimeNanos, durationNanos);
     eventSeq.add(e);
   }
 
   @Override
-  public void devModeSessionEnded(DevModeSession session) {
+  public void devModeSessionBegin(DevModeSession session) {
     // always raise exception here - this method shouldn't be invoked from
     // SpeedTracerLogger
-    Assert.fail("SpeedTracerLogger should not be calling DashboardNotifier.devModeSessionEnded()");
+    Assert.fail("SpeedTracerLogger should not be calling DashboardNotifier.devModeSessionBegin()");
   }
 
   @Override
-  public void devModeSession(DevModeSession session) {
+  public void devModeSessionEnd(DevModeSession session) {
     // always raise exception here - this method shouldn't be invoked from
     // SpeedTracerLogger
-    Assert.fail("SpeedTracerLogger should not be calling DashboardNotifier.devModeSession()");
+    Assert.fail("SpeedTracerLogger should not be calling DashboardNotifier.devModeSessionEnd()");
   }
 
+  /**
+   * Returns the sequence of events posted to the notifier. Also validates that
+   * the notifier is in a valid state (i.e. not between calls to beginning and
+   * ending an event).
+   * 
+   * @return the sequence of events posted to the notifier
+   */
   public LinkedList<DevModeEvent> getEventSequence() {
+    Assert.assertFalse("DashboardNotifier.devModeEventBegin() called without matching "
+        + "call to DashboardNotifier.devModeEventEnd()", started);
     return eventSeq;
   }
 }