-
Bug
-
Resolution: Fixed
-
Critical
Merely calling job.getBuilds().isEmpty() breaks lazy-loading:
at hudson.model.Run.onLoad(Run.java:319) at hudson.model.RunMap.retrieve(RunMap.java:226) at hudson.model.RunMap.retrieve(RunMap.java:59) at jenkins.model.lazy.AbstractLazyLoadRunMap.load(AbstractLazyLoadRunMap.java:667) at jenkins.model.lazy.AbstractLazyLoadRunMap.load(AbstractLazyLoadRunMap.java:650) at jenkins.model.lazy.AbstractLazyLoadRunMap.all(AbstractLazyLoadRunMap.java:602) at jenkins.model.lazy.AbstractLazyLoadRunMap.entrySet(AbstractLazyLoadRunMap.java:264) at java.util.AbstractMap$2$1.<init>(AbstractMap.java:378) at java.util.AbstractMap$2.iterator(AbstractMap.java:377) at hudson.util.RunList$2.iterator(RunList.java:213) at hudson.util.RunList.iterator(RunList.java:103) at hudson.util.RunList.isEmpty(RunList.java:173)
You would reasonably expect this method, and anything simply iterating builds, to be lazy, but it is eager.
- depends on
-
JENKINS-25655 AbstractLazyLoadRunMap.entrySet improperly cached
-
- Resolved
-
- is blocking
-
JENKINS-20892 /{view,computer,user}/*/builds & /job/*/buildTimeTrend block HTTP response on build record loading
-
- Resolved
-
- is duplicated by
-
JENKINS-23244 Slave build history page has no data and spawns a ton of very long-lived blocking threads on the master
-
- Resolved
-
- is related to
-
JENKINS-8754 ROADMAP: Improve Start-up Time
-
- Closed
-
Code changed in jenkins
User: Jesse Glick
Path:
core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java
core/src/test/java/jenkins/model/lazy/FakeMap.java
http://jenkins-ci.org/commit/jenkins/c3e73296b5af0a4aaa06a3bdf867ac50fe211888
Log:
JENKINS-18065Uncommenting original test.The actual implementation does not behave as nicely as one would hope, for a few reasons:
1. isEmpty actually tries to load the newestBuild, rather than simply checking whether there is some idOnDisk.
Arguably this is necessary, since there could be an unloadable build record, in which case it would be technically correct for the map to be considered empty.
2. Loading AbstractLazyLoadRunMap.newestBuild calls search(MAX_VALUE, DESC), which behaves oddly, by doing a binary search, and thus perhaps loading lg(|map|) entries.
You would think that it would suffice to check for the last member of idOnDisk in index.byId.
3. The iterator eagerly loads the next value before hasNext has even been called.
Looks bad in a test, though it probably has little practical impact since most callers would be calling hasNext soon afterward anyway.
Might cause one extra build record to be loaded unnecessarily from a limited RunList.
(cherry picked from commit 2f58ceb1a66c8ed621fa2562c5ed3445b29ea200)