From: Stephane Gamard Date: Thu, 24 Jul 2014 16:28:42 +0000 (+0200) Subject: SONAR-4898 - Fixed hangs when exiting after a failure. X-Git-Tag: 4.5-RC1~361 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a57b9477e3f618f5f6b8ac5f0125fcbb22d46e96;p=sonarqube.git SONAR-4898 - Fixed hangs when exiting after a failure. --- diff --git a/server/sonar-process/src/main/java/org/sonar/process/Monitor.java b/server/sonar-process/src/main/java/org/sonar/process/Monitor.java index 5339226c444..75fd0ef8200 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/Monitor.java +++ b/server/sonar-process/src/main/java/org/sonar/process/Monitor.java @@ -40,14 +40,16 @@ public class Monitor extends Thread { private volatile List processes; private volatile Map pings; + private ProcessWatch processWatch; private ScheduledFuture watch; - private final ScheduledExecutorService monitor; + private ScheduledExecutorService monitor; public Monitor() { processes = new ArrayList(); pings = new HashMap(); monitor = Executors.newScheduledThreadPool(1); - watch = monitor.scheduleWithFixedDelay(new ProcessWatch(), 0, 3, TimeUnit.SECONDS); + processWatch = new ProcessWatch(); + watch = monitor.scheduleWithFixedDelay(processWatch, 0, 3, TimeUnit.SECONDS); } public void registerProcess(ProcessWrapper processWrapper) { @@ -69,9 +71,11 @@ public class Monitor extends Thread { public void run() { for (ProcessWrapper process : processes) { try { - long time = process.getProcessMXBean().ping(); - LOGGER.debug("PINGED '{}'", process.getName()); - pings.put(process.getName(), time); + if (process.getProcessMXBean() != null) { + long time = process.getProcessMXBean().ping(); + LOGGER.debug("PINGED '{}'", process.getName()); + pings.put(process.getName(), time); + } } catch (Exception e) { LOGGER.error("Error while pinging {}", process.getName(), e); } @@ -85,24 +89,30 @@ public class Monitor extends Thread { } public void run() { - boolean everythingOK = true; try { - while (everythingOK) { + while (true) { for (ProcessWrapper process : processes) { if (!processIsValid(process)) { LOGGER.warn("Monitor::run() -- Process '{}' is not valid. Exiting monitor", process.getName()); - everythingOK = false; - break; + this.interrupt(); } } Thread.sleep(3000L); } - } catch (InterruptedException e) { - LOGGER.info("Monitoring thread is interrupted."); + LOGGER.debug("Monitoring thread is interrupted."); } finally { - watch.cancel(true); + terminate(); + } + } + + public void terminate() { + if (monitor != null) { monitor.shutdownNow(); + watch.cancel(true); + watch = null; + processWatch = null; } } + } diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java index 24568612d7c..263e3c6c242 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java @@ -31,7 +31,6 @@ import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; - import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; @@ -155,6 +154,7 @@ public class ProcessWrapper extends Thread { waitUntilFinish(errorGobbler); closeStreams(process); FileUtils.deleteQuietly(propertiesFile); + processMXBean = null; } LOGGER.trace("ProcessWrapper::run() END"); } @@ -254,7 +254,12 @@ public class ProcessWrapper extends Thread { public void terminate() { if (processMXBean != null) { processMXBean.terminate(); - this.interrupt(); + try { + this.join(); + } catch (InterruptedException e) { + // ignore + } + processMXBean = null; } } diff --git a/sonar-application/src/main/java/org/sonar/application/App.java b/sonar-application/src/main/java/org/sonar/application/App.java index f80d2591a5f..a2b63eab3e8 100644 --- a/sonar-application/src/main/java/org/sonar/application/App.java +++ b/sonar-application/src/main/java/org/sonar/application/App.java @@ -26,12 +26,10 @@ import org.sonar.process.Process; import org.sonar.process.ProcessMXBean; import org.sonar.process.ProcessWrapper; -import javax.annotation.Nullable; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; - import java.lang.management.ManagementFactory; public class App implements ProcessMXBean { @@ -114,6 +112,7 @@ public class App implements ProcessMXBean { // TODO ignore ? } finally { + LOGGER.debug("Closing App because monitor is gone."); terminate(); } } @@ -125,20 +124,8 @@ public class App implements ProcessMXBean { logger.info("Shutting down server"); monitor.interrupt(); monitor = null; - terminateAndWait(elasticsearch); - terminateAndWait(server); - } - - } - - private void terminateAndWait(@Nullable ProcessWrapper process) { - if (process != null) { - process.terminate(); - try { - process.join(); - } catch (InterruptedException e) { - LOGGER.warn("Process '{}' did not gracefully shutdown.", process.getName()); - } + elasticsearch.terminate(); + server.terminate(); } }