From 25084f528208a5ab8e0f1ebd9ae80527bf0099d1 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 13 Mar 2013 19:05:24 -0700 Subject: [PATCH] [FIXED JENKINS-3265] Made the in-flight build survive the reload from the disk. --- changelog.html | 3 +++ .../java/hudson/model/AbstractProject.java | 15 +++++++++++++-- core/src/main/java/jenkins/model/Jenkins.java | 19 ++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/changelog.html b/changelog.html index aec20f2b41..c2ced7a701 100644 --- a/changelog.html +++ b/changelog.html @@ -62,6 +62,9 @@ Upcoming changes
  • an in-progress build was dropped from JSON API when lazy-loading was introduced. (issue 15583) +
  • + In-progress builds now survive the "reload from disk" administrator action. + (issue 3265)
  • Fixed a bad interaction between Windows symlinks and build record lazy loading. (issue 15587) diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 90c4a975f7..99fb7054fa 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -282,9 +282,20 @@ public abstract class AbstractProject

    ,R extends A super.onLoad(parent, name); RunMap builds = createBuildRunMap(); - if (this.builds!=null) { + + RunMap currentBuilds = this.builds; + + if (currentBuilds==null) { + // are we overwriting what currently exist? + // this is primarily when Jenkins is getting reloaded + Item current = parent.getItem(name); + if (current!=null && current.getClass()==getClass()) { + currentBuilds = ((AbstractProject)current).builds; + } + } + if (currentBuilds !=null) { // if we are reloading, keep all those that are still building intact - for (R r : this.builds.getLoadedBuilds().values()) { + for (R r : currentBuilds.getLoadedBuilds().values()) { if (r.isBuilding()) builds.put(r); } diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 8ba08f4cae..31e6c5f333 100755 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -2505,6 +2505,8 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro } }); + final Set loadedNames = Collections.synchronizedSet(new HashSet()); + TaskGraphBuilder g = new TaskGraphBuilder(); Handle loadHudson = g.requires(EXTENSIONS_AUGMENTED).attains(JOB_LOADED).add("Loading global config", new Executable() { public void run(Reactor session) throws Exception { @@ -2527,7 +2529,6 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro if (slaves == null) slaves = new NodeList(); clouds.setOwner(Jenkins.this); - items.clear(); // JENKINS-8043: re-add the slaves which were not saved into the config file // and are now missing, but still connected. @@ -2550,10 +2551,26 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro public void run(Reactor session) throws Exception { TopLevelItem item = (TopLevelItem) Items.load(Jenkins.this, subdir); items.put(item.getName(), item); + loadedNames.add(item.getName()); } }); } + g.requires(JOB_LOADED).add("Cleaning up old builds",new Executable() { + public void run(Reactor reactor) throws Exception { + // anything we didn't load from disk, throw them away. + // doing this after loading from disk allows newly loaded items + // to inspect what already existed in memory (in case of reloading) + + // retainAll doesn't work well because of CopyOnWriteMap implementation, so remove one by one + // hopefully there shouldn't be too many of them. + for (String name : items.keySet()) { + if (!loadedNames.contains(name)) + items.remove(name); + } + } + }); + g.requires(JOB_LOADED).add("Finalizing set up",new Executable() { public void run(Reactor session) throws Exception { rebuildDependencyGraph(); -- GitLab