private volatile List<ProcessWrapper> processes;
private volatile Map<String, Long> pings;
+ private ProcessWatch processWatch;
private ScheduledFuture<?> watch;
- private final ScheduledExecutorService monitor;
+ private ScheduledExecutorService monitor;
public Monitor() {
processes = new ArrayList<ProcessWrapper>();
pings = new HashMap<String, Long>();
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) {
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);
}
}
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;
}
}
+
}
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;
waitUntilFinish(errorGobbler);
closeStreams(process);
FileUtils.deleteQuietly(propertiesFile);
+ processMXBean = null;
}
LOGGER.trace("ProcessWrapper::run() END");
}
public void terminate() {
if (processMXBean != null) {
processMXBean.terminate();
- this.interrupt();
+ try {
+ this.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ processMXBean = null;
}
}
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 {
// TODO ignore ?
} finally {
+ LOGGER.debug("Closing App because monitor is gone.");
terminate();
}
}
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();
}
}