提交 d1d52486 编写于 作者: J Jesse Glick

[FIXED JENKINS-18895] MavenModuleSetBuild.getResult is expensive.

上级 1f23168c
...@@ -61,6 +61,9 @@ Upcoming changes</a> ...@@ -61,6 +61,9 @@ Upcoming changes</a>
<li class=bug> <li class=bug>
Maven build failure wasn't describing errors like Maven CLI does. Maven build failure wasn't describing errors like Maven CLI does.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15025">issue 15025</a>) (<a href="https://issues.jenkins-ci.org/browse/JENKINS-15025">issue 15025</a>)
<li class=bug>
<code>MavenModuleSetBuild.getResult</code> is expensive.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18895">issue 18895</a>)
<li class=bug> <li class=bug>
Revisited fix to be compatible for plugins. Revisited fix to be compatible for plugins.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18119">issue 18119</a>) (<a href="https://issues.jenkins-ci.org/browse/JENKINS-18119">issue 18119</a>)
......
...@@ -53,7 +53,6 @@ import hudson.model.Result; ...@@ -53,7 +53,6 @@ import hudson.model.Result;
import hudson.model.Run; import hudson.model.Run;
import hudson.model.StringParameterDefinition; import hudson.model.StringParameterDefinition;
import hudson.model.TaskListener; import hudson.model.TaskListener;
import hudson.remoting.Callable;
import hudson.remoting.VirtualChannel; import hudson.remoting.VirtualChannel;
import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet;
import hudson.tasks.BuildStep; import hudson.tasks.BuildStep;
...@@ -93,7 +92,6 @@ import jenkins.mvn.SettingsProvider; ...@@ -93,7 +92,6 @@ import jenkins.mvn.SettingsProvider;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.versioning.ComparableVersion; import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.ProjectBuildingException;
import org.codehaus.plexus.util.PathTool; import org.codehaus.plexus.util.PathTool;
...@@ -136,6 +134,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven ...@@ -136,6 +134,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
private String mavenVersionUsed; private String mavenVersionUsed;
private transient Object notifyModuleBuildLock = new Object(); private transient Object notifyModuleBuildLock = new Object();
private transient Result effectiveResult;
public MavenModuleSetBuild(MavenModuleSet job) throws IOException { public MavenModuleSetBuild(MavenModuleSet job) throws IOException {
super(job); super(job);
...@@ -194,6 +193,11 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven ...@@ -194,6 +193,11 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
*/ */
@Override @Override
public Result getResult() { public Result getResult() {
synchronized (notifyModuleBuildLock) {
if (effectiveResult != null) {
return effectiveResult;
}
}
Result r = super.getResult(); Result r = super.getResult();
for (MavenBuild b : getModuleLastBuilds().values()) { for (MavenBuild b : getModuleLastBuilds().values()) {
...@@ -208,6 +212,11 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven ...@@ -208,6 +212,11 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
r = r.combine(br); r = r.combine(br);
} }
synchronized (notifyModuleBuildLock) {
if (effectiveResult == null) {
effectiveResult = r;
}
}
return r; return r;
} }
...@@ -522,6 +531,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven ...@@ -522,6 +531,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
// use a separate lock object since this synchronized block calls into plugins, // use a separate lock object since this synchronized block calls into plugins,
// which in turn can access other MavenModuleSetBuild instances, which will result in a dead lock. // which in turn can access other MavenModuleSetBuild instances, which will result in a dead lock.
synchronized(notifyModuleBuildLock) { synchronized(notifyModuleBuildLock) {
effectiveResult = null;
boolean modified = false; boolean modified = false;
List<Action> actions = getActions(); List<Action> actions = getActions();
......
...@@ -50,12 +50,16 @@ public final class RunLoadCounter { ...@@ -50,12 +50,16 @@ public final class RunLoadCounter {
/** /**
* Prepares a new project to be measured. * Prepares a new project to be measured.
* Call this <em>before</em> starting builds. * Usually called before starting builds, but may also be called retroactively.
* @param project a project of any kind * @param project a project of any kind
* @throws IOException if preparations fail * @throws IOException if preparations fail
*/ */
public static void prepare(AbstractProject<?,?> project) throws IOException { public static void prepare(AbstractProject<?,?> project) throws IOException {
project.getPublishersList().add(new MarkerAdder()); project.getPublishersList().add(new MarkerAdder());
for (AbstractBuild<?,?> build : project._getRuns()) {
Marker.add(build);
build.save();
}
} }
/** /**
...@@ -97,6 +101,10 @@ public final class RunLoadCounter { ...@@ -97,6 +101,10 @@ public final class RunLoadCounter {
@Restricted(NoExternalUse.class) @Restricted(NoExternalUse.class)
public static final class Marker implements RunAction { public static final class Marker implements RunAction {
static void add(AbstractBuild<?,?> build) {
build.addAction(new Marker(build.getParent().getFullName(), build.getNumber()));
}
private final String project; private final String project;
private final int build; private final int build;
...@@ -137,7 +145,7 @@ public final class RunLoadCounter { ...@@ -137,7 +145,7 @@ public final class RunLoadCounter {
public static final class MarkerAdder extends Notifier { public static final class MarkerAdder extends Notifier {
@Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { @Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
build.addAction(new Marker(build.getParent().getFullName(), build.getNumber())); Marker.add(build);
return true; return true;
} }
......
...@@ -2,10 +2,12 @@ package hudson.maven; ...@@ -2,10 +2,12 @@ package hudson.maven;
import hudson.model.Result; import hudson.model.Result;
import hudson.tasks.Shell; import hudson.tasks.Shell;
import java.util.concurrent.Callable;
import org.jvnet.hudson.test.Bug; import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.ExtractResourceSCM; import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.HudsonTestCase; import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.RunLoadCounter;
/** /**
* @author Olivier Lamy * @author Olivier Lamy
...@@ -24,10 +26,19 @@ public class MavenBuildSurefireFailedTest extends HudsonTestCase { ...@@ -24,10 +26,19 @@ public class MavenBuildSurefireFailedTest extends HudsonTestCase {
@Bug(8415) @Bug(8415)
public void testMaven2Failed() throws Exception { public void testMaven2Failed() throws Exception {
configureDefaultMaven(); configureDefaultMaven();
MavenModuleSet m = createMavenProject(); final MavenModuleSet m = createMavenProject();
m.setGoals( "test -Dmaven.test.failure.ignore=false" ); m.setGoals( "test -Dmaven.test.failure.ignore=false" );
m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimodule-unit-failure.zip"))); m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimodule-unit-failure.zip")));
assertBuildStatus(Result.FAILURE, m.scheduleBuild2(0).get()); assertBuildStatus(Result.FAILURE, m.scheduleBuild2(0).get());
// JENKINS-18895:
MavenModule failing = m.getModule("com.mycompany.app:my-app");
assertEquals(Result.FAILURE, failing.getLastBuild().getResult());
RunLoadCounter.prepare(failing);
assertEquals(Result.FAILURE, RunLoadCounter.assertMaxLoads(failing, 0, new Callable<Result>() {
@Override public Result call() throws Exception {
return m.getLastBuild().getResult();
}
}));
} }
@Bug(8415) @Bug(8415)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册