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

[FIXED JENKINS-15747] Avoid recording too many upstream causes at any depth.

上级 9e58d944
...@@ -67,6 +67,9 @@ Upcoming changes</a> ...@@ -67,6 +67,9 @@ Upcoming changes</a>
<li class=bug> <li class=bug>
Plugin icons in the sidebar were not being properly cached. Plugin icons in the sidebar were not being properly cached.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16530">issue 16530</a>) (<a href="https://issues.jenkins-ci.org/browse/JENKINS-16530">issue 16530</a>)
<li class='major bug'>
Broadly as well as deeply nested build causes overwhelmed the UI after 1.482.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15747">issue 15747</a>)
<li class=bug> <li class=bug>
API typo <code>DependecyDeclarer</code> corrected. API typo <code>DependecyDeclarer</code> corrected.
<li class=bug> <li class=bug>
......
...@@ -34,6 +34,7 @@ import jenkins.model.Jenkins; ...@@ -34,6 +34,7 @@ import jenkins.model.Jenkins;
import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.ExportedBean;
import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
...@@ -106,6 +107,10 @@ public abstract class Cause { ...@@ -106,6 +107,10 @@ public abstract class Cause {
* Maximum depth of transitive upstream causes we want to record. * Maximum depth of transitive upstream causes we want to record.
*/ */
private static final int MAX_DEPTH = 10; private static final int MAX_DEPTH = 10;
/**
* Maximum number of transitive upstream causes we want to record.
*/
private static final int MAX_LEAF = 25;
private String upstreamProject, upstreamUrl; private String upstreamProject, upstreamUrl;
private int upstreamBuild; private int upstreamBuild;
/** /**
...@@ -128,8 +133,9 @@ public abstract class Cause { ...@@ -128,8 +133,9 @@ public abstract class Cause {
upstreamProject = up.getParent().getFullName(); upstreamProject = up.getParent().getFullName();
upstreamUrl = up.getParent().getUrl(); upstreamUrl = up.getParent().getUrl();
upstreamCauses = new ArrayList<Cause>(); upstreamCauses = new ArrayList<Cause>();
AtomicInteger leaf = new AtomicInteger(MAX_LEAF);
for (Cause c : up.getCauses()) { for (Cause c : up.getCauses()) {
upstreamCauses.add(trim(c, MAX_DEPTH)); upstreamCauses.add(trim(c, MAX_DEPTH, leaf));
} }
} }
...@@ -140,7 +146,7 @@ public abstract class Cause { ...@@ -140,7 +146,7 @@ public abstract class Cause {
this.upstreamCauses = upstreamCauses; this.upstreamCauses = upstreamCauses;
} }
private @Nonnull Cause trim(@Nonnull Cause c, int depth) { private @Nonnull Cause trim(@Nonnull Cause c, int depth, AtomicInteger leaf) {
if (!(c instanceof UpstreamCause)) { if (!(c instanceof UpstreamCause)) {
return c; return c;
} }
...@@ -148,7 +154,11 @@ public abstract class Cause { ...@@ -148,7 +154,11 @@ public abstract class Cause {
List<Cause> cs = new ArrayList<Cause>(); List<Cause> cs = new ArrayList<Cause>();
if (depth > 0) { if (depth > 0) {
for (Cause c2 : uc.upstreamCauses) { for (Cause c2 : uc.upstreamCauses) {
cs.add(trim(c2, depth - 1)); if (leaf.decrementAndGet() > 0) {
cs.add(trim(c2, depth - 1, leaf));
} else {
cs.add(new DeeplyNestedUpstreamCause());
}
} }
} else { } else {
cs.add(new DeeplyNestedUpstreamCause()); cs.add(new DeeplyNestedUpstreamCause());
......
...@@ -26,6 +26,8 @@ package hudson.model; ...@@ -26,6 +26,8 @@ package hudson.model;
import hudson.XmlFile; import hudson.XmlFile;
import java.io.File; import java.io.File;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -54,4 +56,27 @@ public class CauseTest { ...@@ -54,4 +56,27 @@ public class CauseTest {
assertFalse("too big:\n" + buildXml, buildXml.contains("<upstreamBuild>1</upstreamBuild>")); assertFalse("too big:\n" + buildXml, buildXml.contains("<upstreamBuild>1</upstreamBuild>"));
} }
@Bug(15747)
@Test public void broadlyNestedCauses() throws Exception {
FreeStyleProject a = j.createFreeStyleProject("a");
FreeStyleProject b = j.createFreeStyleProject("b");
FreeStyleProject c = j.createFreeStyleProject("c");
Run<?,?> last = null;
for (int i = 1; i <= 10; i++) {
Cause cause = last == null ? null : new Cause.UpstreamCause(last);
Future<? extends Run<?,?>> next1 = a.scheduleBuild2(0, cause);
a.scheduleBuild2(0, cause);
cause = new Cause.UpstreamCause(next1.get());
Future<? extends Run<?,?>> next2 = b.scheduleBuild2(0, cause);
b.scheduleBuild2(0, cause);
cause = new Cause.UpstreamCause(next2.get());
Future<? extends Run<?,?>> next3 = c.scheduleBuild2(0, cause);
c.scheduleBuild2(0, cause);
last = next3.get();
}
int count = new XmlFile(Run.XSTREAM, new File(last.getRootDir(), "build.xml")).asString().split(Pattern.quote("<hudson.model.Cause_-UpstreamCause")).length;
assertFalse("too big at " + count, count > 100);
//j.interactiveBreak();
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册