--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
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() {
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;
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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;
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;
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;
}
}
+ 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()) {
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;
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);
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);
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);
}
initializerPhase(profiler);
sensorPhase(profiler);
decoratorPhase(profiler);
+ persistersPhase(profiler);
postJobPhase(profiler);
batchStep(profiler);
// End of moduleA
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
};
}
+ 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() {
};
}
+ 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() {
public void executeOn(Project project, SensorContext context) {
}
}
+
+ public class FakeScanPersister implements ScanPersister {
+ @Override
+ public void persist() {
+ }
+ }
}