ignore non-deterministic build failure and log it.

maven builds intermittently fail due to something in the code.
essentially its the same issue as in bug 1201035.

This patch makes it so the build ignores the error and just logs
it so that we can have a record of the error.  Hopefully we
can use logstash to query for a pattern to determine the
root cause of this problem.

The error on this build:
  java.lang.NullPointerException
      at hudson.plugins.gearman.ExecutorWorkerThread.registerJobs(ExecutorWorkerThread.java:150)
      at hudson.plugins.gearman.SaveableListenerImpl.onChange(SaveableListenerImpl.java:68)
      at hudson.model.listeners.SaveableListener.fireOnChange(SaveableListener.java:78)
      at hudson.model.AbstractItem.save(AbstractItem.java:474)
      at hudson.model.Job.save(Job.java:154)
      at hudson.model.AbstractProject.save(AbstractProject.java:273)
      at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.parsePoms(MavenModuleSetBuild.java:915)
      at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:622)
      at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:586)
      at hudson.model.Run.execute(Run.java:1575)
      at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:477)
      at hudson.model.ResourceController.execute(ResourceController.java:88)
      at hudson.model.Executor.run(Executor.java:241)

Change-Id: I16fb0261312fe0aef55d2f2b6c83652333aed05a
This commit is contained in:
zaro0508 2013-07-15 11:27:12 -07:00
parent 1e2fdcc524
commit 13b4b52968
1 changed files with 48 additions and 41 deletions

View File

@ -19,9 +19,9 @@
package hudson.plugins.gearman; package hudson.plugins.gearman;
import hudson.model.AbstractProject; import hudson.model.AbstractProject;
import hudson.model.Computer;
import hudson.model.Label; import hudson.model.Label;
import hudson.model.Node; import hudson.model.Node;
import hudson.model.Computer;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -32,7 +32,6 @@ import java.util.Set;
import jenkins.model.Jenkins; import jenkins.model.Jenkins;
import org.gearman.worker.GearmanFunctionFactory; import org.gearman.worker.GearmanFunctionFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -63,6 +62,7 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
this.masterName = masterName; this.masterName = masterName;
} }
@Override
protected void initWorker() { protected void initWorker() {
availability.unlock(worker); availability.unlock(worker);
super.initWorker(); super.initWorker();
@ -147,54 +147,61 @@ public class ExecutorWorkerThread extends AbstractWorkerThread{
public void registerJobs() { public void registerJobs() {
HashMap<String,GearmanFunctionFactory> newFunctionMap = new HashMap<String,GearmanFunctionFactory>(); HashMap<String,GearmanFunctionFactory> newFunctionMap = new HashMap<String,GearmanFunctionFactory>();
if (!this.node.toComputer().isOffline()) { try {
List<AbstractProject> allProjects = Jenkins.getInstance().getAllItems(AbstractProject.class); Node n = getNode();
for (AbstractProject<?, ?> project : allProjects) { Computer c = n.toComputer();
if (project.isDisabled()) { // ignore all disabled projects if (!c.isOffline()) {
continue; List<AbstractProject> allProjects = Jenkins.getInstance().getAllItems(AbstractProject.class);
} for (AbstractProject<?, ?> project : allProjects) {
String projectName = project.getName(); if (project.isDisabled()) { // ignore all disabled projects
Label label = project.getAssignedLabel(); continue;
}
if (label == null) { // project has no label -> so register String projectName = project.getName();
// "build:projectName" on all nodes Label label = project.getAssignedLabel();
String jobFunctionName = "build:" + projectName;
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, this.node, this.masterName, worker));
} else { // register "build:$projectName:$projectLabel" if this
// node matches a node from the project label
Set<Node> projectLabelNodes = label.getNodes(); if (label == null) { // project has no label -> so register
String projectLabelString = label.getExpression(); // "build:projectName" on all nodes
Set<String> projectLabels = tokenizeLabelString( String jobFunctionName = "build:" + projectName;
projectLabelString, "\\|\\|"); newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, n, this.masterName, worker));
} else { // register "build:$projectName:$projectLabel" if this
// node matches a node from the project label
// iterate thru all project labels and find matching nodes Set<Node> projectLabelNodes = label.getNodes();
for (String projectLabel : projectLabels) { String projectLabelString = label.getExpression();
if (projectLabelNodes.contains(this.node)) { Set<String> projectLabels = tokenizeLabelString(
String jobFunctionName = "build:" + projectName projectLabelString, "\\|\\|");
+ ":" + projectLabel;
// register with label (i.e. "build:$projectName:$projectLabel") // iterate thru all project labels and find matching nodes
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory( for (String projectLabel : projectLabels) {
jobFunctionName, StartJobWorker.class.getName(), if (projectLabelNodes.contains(n)) {
project, this.node, this.masterName, worker)); String jobFunctionName = "build:" + projectName
jobFunctionName = "build:" + projectName; + ":" + projectLabel;
// also register without label (i.e. "build:$projectName") // register with label (i.e. "build:$projectName:$projectLabel")
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory( newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(), jobFunctionName, StartJobWorker.class.getName(),
project, this.node, this.masterName, worker)); project, n, this.masterName, worker));
jobFunctionName = "build:" + projectName;
// also register without label (i.e. "build:$projectName")
newFunctionMap.put(jobFunctionName, new CustomGearmanFunctionFactory(
jobFunctionName, StartJobWorker.class.getName(),
project, n, this.masterName, worker));
}
} }
} }
} }
} }
} if (!newFunctionMap.keySet().equals(functionMap.keySet())) {
if (!newFunctionMap.keySet().equals(functionMap.keySet())) { functionMap = newFunctionMap;
functionMap = newFunctionMap; Set<GearmanFunctionFactory> functionSet = new HashSet<GearmanFunctionFactory>(functionMap.values());
Set<GearmanFunctionFactory> functionSet = new HashSet<GearmanFunctionFactory>(functionMap.values()); updateJobs(functionSet);
updateJobs(functionSet); }
} catch (NullPointerException npe) {
logger.warn("Failed to register jobs on worker thread: "+getName()+" with worker: "+worker.getWorkerID(), npe);
} }
} }