From c9f779dc009b42cf8e1bc5c5a335462be0c3e971 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 30 Aug 2017 16:30:36 +0200 Subject: [PATCH] SONAR-9715 improve documentation of process management --- .../main/java/org/sonar/ce/app/CeServer.java | 13 +++++-------- .../ce/container/ComputeEngineStatus.java | 2 +- .../process/ProcessLauncherImpl.java | 4 ++-- .../java/org/sonar/process/Monitored.java | 10 +++++++++- .../org/sonar/process/ProcessEntryPoint.java | 4 ++-- .../java/org/sonar/process/StopperThread.java | 19 ++++++++----------- .../sonar/process/ProcessEntryPointTest.java | 4 ++-- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/app/CeServer.java b/server/sonar-ce/src/main/java/org/sonar/ce/app/CeServer.java index 82b9f1ecc44..129c65ef502 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/app/CeServer.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/app/CeServer.java @@ -22,7 +22,7 @@ package org.sonar.ce.app; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.ce.ComputeEngine; @@ -56,7 +56,7 @@ public class CeServer implements Monitored { private volatile boolean stopAwait = false; private final ComputeEngine computeEngine; - @CheckForNull + @Nullable private CeMainThread ceMainThread = null; @VisibleForTesting @@ -172,6 +172,7 @@ public class CeServer implements Monitored { Thread.sleep(CHECK_FOR_STOP_DELAY); } catch (InterruptedException e) { // ignore the interruption itself, check the flag + Thread.currentThread().interrupt(); } } attemptShutdown(); @@ -179,7 +180,8 @@ public class CeServer implements Monitored { private void attemptShutdown() { try { - shutdown(); + LOG.info("Compute Engine shutting down..."); + computeEngine.shutdown(); } catch (Throwable e) { LOG.error("Compute Engine shutdown failed", e); } finally { @@ -188,11 +190,6 @@ public class CeServer implements Monitored { } } - private void shutdown() { - LOG.info("Compute Engine shutting down..."); - computeEngine.shutdown(); - } - public boolean isStarted() { return started; } diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineStatus.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineStatus.java index 600128e9bf6..b19b2fad147 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineStatus.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineStatus.java @@ -27,6 +27,6 @@ public interface ComputeEngineStatus { Status getStatus(); enum Status { - INIT, STARTING, STARTED, STOPPING, STOPPED; + INIT, STARTING, STARTED, STOPPING, STOPPED } } diff --git a/server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncherImpl.java b/server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncherImpl.java index 3c2816474a7..af17e5ff80b 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncherImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/process/ProcessLauncherImpl.java @@ -44,7 +44,7 @@ import static java.lang.String.format; import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_INDEX; import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_KEY; import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH; -import static org.sonar.process.ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT; +import static org.sonar.process.ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT_MS; public class ProcessLauncherImpl implements ProcessLauncher { private static final Logger LOG = LoggerFactory.getLogger(ProcessLauncherImpl.class); @@ -182,7 +182,7 @@ public class ProcessLauncherImpl implements ProcessLauncher { props.putAll(javaCommand.getArguments()); props.setProperty(PROPERTY_PROCESS_KEY, javaCommand.getProcessId().getKey()); props.setProperty(PROPERTY_PROCESS_INDEX, Integer.toString(javaCommand.getProcessId().getIpcIndex())); - props.setProperty(PROPERTY_TERMINATION_TIMEOUT, "60000"); + props.setProperty(PROPERTY_TERMINATION_TIMEOUT_MS, "60000"); props.setProperty(PROPERTY_SHARED_PATH, tempDir.getAbsolutePath()); try (OutputStream out = new FileOutputStream(propertiesFile)) { props.store(out, format("Temporary properties file for command [%s]", javaCommand.getProcessId().getKey())); diff --git a/server/sonar-process/src/main/java/org/sonar/process/Monitored.java b/server/sonar-process/src/main/java/org/sonar/process/Monitored.java index b37d929e54d..2fa65b1c571 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/Monitored.java +++ b/server/sonar-process/src/main/java/org/sonar/process/Monitored.java @@ -19,6 +19,11 @@ */ package org.sonar.process; +/** + * Base interface for the processes started by the bootstrap process. + * It provides the information and operations required by {@link ProcessEntryPoint} + * to handle the lifecycle of the process. + */ public interface Monitored { /** @@ -37,9 +42,12 @@ public interface Monitored { } /** - * Blocks until the process is terminated + * Blocks until the process is stopped */ void awaitStop(); + /** + * Stop process and wait until it's stopped. + */ void stop(); } diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java index b1476fba53e..76b89a007f9 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java @@ -29,7 +29,7 @@ public class ProcessEntryPoint implements Stoppable { public static final String PROPERTY_PROCESS_KEY = "process.key"; public static final String PROPERTY_PROCESS_INDEX = "process.index"; - public static final String PROPERTY_TERMINATION_TIMEOUT = "process.terminationTimeout"; + public static final String PROPERTY_TERMINATION_TIMEOUT_MS = "process.terminationTimeout"; public static final String PROPERTY_SHARED_PATH = "process.sharedDir"; private final Props props; @@ -171,7 +171,7 @@ public class ProcessEntryPoint implements Stoppable { @Override public void stopAsync() { if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) { - stopperThread = new StopperThread(monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT))); + stopperThread = new StopperThread(monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT_MS))); stopperThread.start(); stopWatcher.stopWatching(); } diff --git a/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java b/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java index 746cd31dc1e..14fe192cd9c 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java +++ b/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java @@ -27,35 +27,32 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.sonar.process.sharedmemoryfile.ProcessCommands; +import static java.lang.String.format; + /** * Gracefully stops process in a timely fashion */ class StopperThread extends Thread { private final Monitored monitored; - private final long terminationTimeout; + private final long terminationTimeoutMs; private final ProcessCommands commands; - StopperThread(Monitored monitored, ProcessCommands commands, long terminationTimeout) { + StopperThread(Monitored monitored, ProcessCommands commands, long terminationTimeoutMs) { super("Stopper"); this.monitored = monitored; - this.terminationTimeout = terminationTimeout; + this.terminationTimeoutMs = terminationTimeoutMs; this.commands = commands; } @Override public void run() { ExecutorService executor = Executors.newSingleThreadExecutor(); - Future future = executor.submit(new Runnable() { - @Override - public void run() { - monitored.stop(); - } - }); try { - future.get(terminationTimeout, TimeUnit.MILLISECONDS); + Future future = executor.submit(monitored::stop); + future.get(terminationTimeoutMs, TimeUnit.MILLISECONDS); } catch (Exception e) { - LoggerFactory.getLogger(getClass()).error(String.format("Can not stop in %dms", terminationTimeout), e); + LoggerFactory.getLogger(getClass()).error(format("Can not stop in %dms", terminationTimeoutMs), e); } executor.shutdownNow(); commands.endWatch(); diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java index 3b7a4659d31..ccffe816e58 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java @@ -40,7 +40,7 @@ import static org.mockito.Mockito.mock; import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_INDEX; import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_KEY; import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH; -import static org.sonar.process.ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT; +import static org.sonar.process.ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT_MS; public class ProcessEntryPointTest { @@ -159,7 +159,7 @@ public class ProcessEntryPointTest { props.set(PROPERTY_SHARED_PATH, temp.newFolder().getAbsolutePath()); props.set(PROPERTY_PROCESS_INDEX, "1"); props.set(PROPERTY_PROCESS_KEY, "test"); - props.set(PROPERTY_TERMINATION_TIMEOUT, "30000"); + props.set(PROPERTY_TERMINATION_TIMEOUT_MS, "30000"); return props; } -- 2.39.5