]> source.dussan.org Git - sonarqube.git/commitdiff
Add details of persisters in profiling output to ease understanding
authorJulien HENRY <julien.henry@sonarsource.com>
Fri, 29 Aug 2014 13:22:50 +0000 (15:22 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Fri, 29 Aug 2014 13:22:50 +0000 (15:22 +0200)
sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/Phases.java
sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java
sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java

diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java
new file mode 100644 (file)
index 0000000..cb65745
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.phases;
+
+import org.sonar.batch.index.ScanPersister;
+import org.sonar.batch.phases.event.PersisterExecutionHandler;
+
+class PersisterExecutionEvent extends AbstractPhaseEvent<PersisterExecutionHandler>
+  implements PersisterExecutionHandler.PersisterExecutionEvent {
+
+  private final ScanPersister persister;
+
+  PersisterExecutionEvent(ScanPersister persister, boolean start) {
+    super(start);
+    this.persister = persister;
+  }
+
+  @Override
+  public ScanPersister getPersister() {
+    return persister;
+  }
+
+  @Override
+  public void dispatch(PersisterExecutionHandler handler) {
+    handler.onPersisterExecution(this);
+  }
+
+  @Override
+  public Class getType() {
+    return PersisterExecutionHandler.class;
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java
new file mode 100644 (file)
index 0000000..c2074ef
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.phases;
+
+import org.sonar.batch.index.ScanPersister;
+import org.sonar.batch.phases.event.PersistersPhaseHandler;
+
+import java.util.List;
+
+class PersistersPhaseEvent extends AbstractPhaseEvent<PersistersPhaseHandler>
+  implements PersistersPhaseHandler.PersistersPhaseEvent {
+
+  private final List<ScanPersister> persisters;
+
+  PersistersPhaseEvent(List<ScanPersister> persisters, boolean start) {
+    super(start);
+    this.persisters = persisters;
+  }
+
+  public List<ScanPersister> getPersisters() {
+    return persisters;
+  }
+
+  @Override
+  protected void dispatch(PersistersPhaseHandler handler) {
+    handler.onPersistersPhase(this);
+  }
+
+  @Override
+  protected Class getType() {
+    return PersistersPhaseHandler.class;
+  }
+
+}
index 5fc37a64dfdbb5b068f4cedd347b981da5f7418b..c08312ce36cc48f1f847c90d2475f24cadf409ea 100644 (file)
@@ -138,14 +138,15 @@ public final class PhaseExecutor {
 
   private void executePersisters() {
     LOGGER.info("Store results in database");
-    String persistersStep = "Persisters";
-    eventBus.fireEvent(new BatchStepEvent(persistersStep, true));
+    eventBus.fireEvent(new PersistersPhaseEvent(Lists.newArrayList(persisters), true));
     for (ScanPersister persister : persisters) {
       LOGGER.debug("Execute {}", persister.getClass().getName());
+      eventBus.fireEvent(new PersisterExecutionEvent(persister, true));
       persister.persist();
+      eventBus.fireEvent(new PersisterExecutionEvent(persister, false));
     }
 
-    eventBus.fireEvent(new BatchStepEvent(persistersStep, false));
+    eventBus.fireEvent(new PersistersPhaseEvent(Lists.newArrayList(persisters), false));
   }
 
   private void updateStatusJob() {
index 44b817907af0d10ae5a0d5f834867a42020bcdf0..4ce24c70a6b514c1bcba1e31e99e54bc21ff063b 100644 (file)
@@ -27,7 +27,7 @@ import java.util.Set;
 public class Phases {
 
   public static enum Phase {
-    MAVEN("Maven"), INIT("Initializers"), SENSOR("Sensors"), DECORATOR("Decorators"), POSTJOB("Post-Jobs");
+    MAVEN("Maven"), INIT("Initializers"), SENSOR("Sensors"), DECORATOR("Decorators"), PERSISTER("Persisters"), POSTJOB("Post-Jobs");
 
     private final String label;
 
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java
new file mode 100644 (file)
index 0000000..7df8dae
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.phases.event;
+
+import org.sonar.api.batch.events.EventHandler;
+import org.sonar.batch.index.ScanPersister;
+
+public interface PersisterExecutionHandler extends EventHandler {
+
+  /**
+   * This interface is not intended to be implemented by clients.
+   */
+  interface PersisterExecutionEvent {
+
+    ScanPersister getPersister();
+
+    boolean isStart();
+
+    boolean isEnd();
+
+  }
+
+  /**
+   * Called before and after execution of {@link ScanPersister}.
+   */
+  void onPersisterExecution(PersisterExecutionEvent event);
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java
new file mode 100644 (file)
index 0000000..087755b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.phases.event;
+
+import org.sonar.api.batch.events.EventHandler;
+import org.sonar.batch.index.ScanPersister;
+
+import java.util.List;
+
+public interface PersistersPhaseHandler extends EventHandler {
+
+  /**
+   * This interface is not intended to be implemented by clients.
+   */
+  interface PersistersPhaseEvent {
+
+    /**
+     * @return list of Persisters in the order of execution
+     */
+    List<ScanPersister> getPersisters();
+
+    boolean isStart();
+
+    boolean isEnd();
+
+  }
+
+  /**
+   * Called before and after execution of all {@link ScanPersister}s.
+   */
+  void onPersistersPhase(PersistersPhaseEvent event);
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java
new file mode 100644 (file)
index 0000000..6aefbe5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.phases.event;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index c2eec6f34a5060fcb3185ece6bcde50df7dd75bd..42d61fb4f64d7d8a6f2a8db917cea5d61ef614b2 100644 (file)
@@ -25,12 +25,23 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.events.*;
+import org.sonar.api.batch.events.DecoratorExecutionHandler;
+import org.sonar.api.batch.events.DecoratorsPhaseHandler;
+import org.sonar.api.batch.events.InitializerExecutionHandler;
+import org.sonar.api.batch.events.InitializersPhaseHandler;
+import org.sonar.api.batch.events.MavenPhaseHandler;
+import org.sonar.api.batch.events.PostJobExecutionHandler;
+import org.sonar.api.batch.events.PostJobsPhaseHandler;
+import org.sonar.api.batch.events.ProjectAnalysisHandler;
+import org.sonar.api.batch.events.SensorExecutionHandler;
+import org.sonar.api.batch.events.SensorsPhaseHandler;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.TimeUtils;
 import org.sonar.batch.events.BatchStepHandler;
 import org.sonar.batch.phases.Phases;
+import org.sonar.batch.phases.event.PersisterExecutionHandler;
+import org.sonar.batch.phases.event.PersistersPhaseHandler;
 
 import javax.annotation.Nullable;
 
@@ -43,7 +54,8 @@ import static org.sonar.batch.profiling.AbstractTimeProfiling.sortByDescendingTo
 import static org.sonar.batch.profiling.AbstractTimeProfiling.truncate;
 
 public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorExecutionHandler, DecoratorExecutionHandler, PostJobExecutionHandler, DecoratorsPhaseHandler,
-  SensorsPhaseHandler, PostJobsPhaseHandler, MavenPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler {
+  SensorsPhaseHandler, PostJobsPhaseHandler, MavenPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler, PersistersPhaseHandler,
+  PersisterExecutionHandler {
 
   static final Logger LOG = LoggerFactory.getLogger(PhasesSumUpTimeProfiler.class);
   private static final int TEXT_RIGHT_PAD = 60;
@@ -137,6 +149,23 @@ public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorEx
     }
   }
 
+  public void onPersistersPhase(PersistersPhaseEvent event) {
+    if (event.isStart()) {
+      currentModuleProfiling.addPhaseProfiling(Phases.Phase.PERSISTER);
+    } else {
+      currentModuleProfiling.getProfilingPerPhase(Phases.Phase.PERSISTER).stop();
+    }
+  }
+
+  public void onPersisterExecution(PersisterExecutionEvent event) {
+    PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phases.Phase.PERSISTER);
+    if (event.isStart()) {
+      profiling.newItemProfiling(event.getPersister());
+    } else {
+      profiling.getProfilingPerItem(event.getPersister()).stop();
+    }
+  }
+
   public void onDecoratorExecution(DecoratorExecutionEvent event) {
     PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phases.Phase.DECORATOR);
     if (event.isStart()) {
index bb8096f8a837ee5bfb8249d38263585bd7e7920d..ad19f8fd1c9c10f5354cf4b208e90c0c0aa478a1 100644 (file)
@@ -44,7 +44,10 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.utils.System2;
 import org.sonar.batch.events.BatchStepEvent;
+import org.sonar.batch.index.ScanPersister;
 import org.sonar.batch.phases.Phases.Phase;
+import org.sonar.batch.phases.event.PersisterExecutionHandler;
+import org.sonar.batch.phases.event.PersistersPhaseHandler;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -77,6 +80,7 @@ public class PhasesSumUpTimeProfilerTest {
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.INIT).getProfilingPerItem(new FakeInitializer()).totalTime()).isEqualTo(7L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
+    assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerBatchStep("Free memory").totalTime()).isEqualTo(9L);
 
@@ -98,6 +102,7 @@ public class PhasesSumUpTimeProfilerTest {
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(10L);
+    assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
     assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
 
     assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.MAVEN).totalTime()).isEqualTo(12L);
@@ -105,6 +110,7 @@ public class PhasesSumUpTimeProfilerTest {
     assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(30L);
     assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(60L);
     assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(30L);
+    assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(120L);
     assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(90L);
   }
 
@@ -153,6 +159,7 @@ public class PhasesSumUpTimeProfilerTest {
     initializerPhase(profiler);
     sensorPhase(profiler);
     decoratorPhase(profiler);
+    persistersPhase(profiler);
     postJobPhase(profiler);
     batchStep(profiler);
     // End of moduleA
@@ -230,6 +237,19 @@ public class PhasesSumUpTimeProfilerTest {
     profiler.onSensorsPhase(sensorsEvent(false));
   }
 
+  private void persistersPhase(PhasesSumUpTimeProfiler profiler) throws InterruptedException {
+    ScanPersister persister = new FakeScanPersister();
+    // Start of persister phase
+    profiler.onPersistersPhase(persistersEvent(true));
+    // Start of a ScanPersister
+    profiler.onPersisterExecution(persisterEvent(persister, true));
+    clock.sleep(40);
+    // End of a ScanPersister
+    profiler.onPersisterExecution(persisterEvent(persister, false));
+    // End of persister phase
+    profiler.onPersistersPhase(persistersEvent(false));
+  }
+
   private void postJobPhase(PhasesSumUpTimeProfiler profiler) throws InterruptedException {
     PostJob postJob = new FakePostJob();
     // Start of sensor phase
@@ -323,6 +343,26 @@ public class PhasesSumUpTimeProfilerTest {
     };
   }
 
+  private PersisterExecutionHandler.PersisterExecutionEvent persisterEvent(final ScanPersister persister, final boolean start) {
+    return new PersisterExecutionHandler.PersisterExecutionEvent() {
+
+      @Override
+      public boolean isStart() {
+        return start;
+      }
+
+      @Override
+      public boolean isEnd() {
+        return !start;
+      }
+
+      @Override
+      public ScanPersister getPersister() {
+        return persister;
+      }
+    };
+  }
+
   private SensorsPhaseEvent sensorsEvent(final boolean start) {
     return new SensorsPhaseHandler.SensorsPhaseEvent() {
 
@@ -398,6 +438,26 @@ public class PhasesSumUpTimeProfilerTest {
     };
   }
 
+  private PersistersPhaseHandler.PersistersPhaseEvent persistersEvent(final boolean start) {
+    return new PersistersPhaseHandler.PersistersPhaseEvent() {
+
+      @Override
+      public boolean isStart() {
+        return start;
+      }
+
+      @Override
+      public boolean isEnd() {
+        return !start;
+      }
+
+      @Override
+      public List<ScanPersister> getPersisters() {
+        return null;
+      }
+    };
+  }
+
   private DecoratorsPhaseHandler.DecoratorsPhaseEvent decoratorsEvent(final boolean start) {
     return new DecoratorsPhaseHandler.DecoratorsPhaseEvent() {
 
@@ -486,4 +546,10 @@ public class PhasesSumUpTimeProfilerTest {
     public void executeOn(Project project, SensorContext context) {
     }
   }
+
+  public class FakeScanPersister implements ScanPersister {
+    @Override
+    public void persist() {
+    }
+  }
 }