aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Process.java69
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java15
2 files changed, 35 insertions, 49 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Process.java b/server/sonar-process/src/main/java/org/sonar/process/Process.java
index b04b2ec0eff..35604e185b9 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/Process.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/Process.java
@@ -30,6 +30,10 @@ import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
public abstract class Process implements ProcessMXBean {
@@ -37,10 +41,7 @@ public abstract class Process implements ProcessMXBean {
public static final String PORT_PROPERTY = "pPort";
public static final String MISSING_NAME_ARGUMENT = "Missing Name argument";
- public static final String MISSING_PORT_ARGUMENT = "Missing Port argument";
- private final Thread monitoringThread;
- private static final long MAX_ALLOWED_TIME = 3000L;
private final static Logger LOGGER = LoggerFactory.getLogger(Process.class);
@@ -51,6 +52,20 @@ public abstract class Process implements ProcessMXBean {
final protected Props props;
+ private static final long MAX_ALLOWED_TIME = 3000L;
+ private ScheduledFuture<?> pingTask = null;
+ final ScheduledExecutorService monitor = Executors.newScheduledThreadPool(1);
+ final Runnable breakOnMissingPing = new Runnable() {
+ public void run() {
+ long time = System.currentTimeMillis();
+ LOGGER.info("last check-in was {}ms ago.", time - lastPing);
+ if (time - lastPing > MAX_ALLOWED_TIME) {
+ LOGGER.warn("Did not get a check-in since {}ms. Initiate shutdown", time - lastPing);
+ stop();
+ }
+ }
+ };
+
public Process(Props props) {
// Loading all Properties from file
@@ -64,12 +79,6 @@ public abstract class Process implements ProcessMXBean {
throw new IllegalStateException(MISSING_NAME_ARGUMENT);
}
- if (this.port != null) {
- this.monitoringThread = new Thread(new Monitor(this));
- } else {
- this.monitoringThread = null;
- }
-
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
try {
mbeanServer.registerMBean(this, this.getObjectName());
@@ -83,6 +92,10 @@ public abstract class Process implements ProcessMXBean {
}
public ObjectName getObjectName() {
+ return objectNameFor(name);
+ }
+
+ static public ObjectName objectNameFor(String name) {
try {
return new ObjectName("org.sonar", "name", name);
} catch (MalformedObjectNameException e) {
@@ -100,9 +113,9 @@ public abstract class Process implements ProcessMXBean {
public final void start() {
LOGGER.info("Process[{}]::start START", name);
- if (monitoringThread != null) {
- this.lastPing = System.currentTimeMillis();
- monitoringThread.start();
+ if (this.port != null) {
+ lastPing = System.currentTimeMillis();
+ pingTask = monitor.scheduleWithFixedDelay(breakOnMissingPing, 0, 3, TimeUnit.SECONDS);
}
this.onStart();
LOGGER.info("Process[{}]::start END", name);
@@ -110,37 +123,11 @@ public abstract class Process implements ProcessMXBean {
public final void stop() {
LOGGER.info("Process[{}]::shutdown START", name);
- if (monitoringThread != null) {
- monitoringThread.interrupt();
+ if (pingTask != null) {
+ pingTask.cancel(true);
}
+ monitor.shutdownNow();
this.onStop();
LOGGER.info("Process[{}]::shutdown END", name);
}
-
-
- private class Monitor implements Runnable {
-
- final Process process;
-
- private Monitor(Process process) {
- this.process = process;
- }
-
- @Override
- public void run() {
- while (monitoringThread != null && !monitoringThread.isInterrupted()) {
- long time = System.currentTimeMillis();
- LOGGER.info("Process[{}]::Monitor::run - last checked-in is {}ms", name, time - lastPing);
- if (time - lastPing > MAX_ALLOWED_TIME) {
- process.stop();
- break;
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
} \ No newline at end of file
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
index a94e53cde64..08e7d24a5b4 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessTest.java
@@ -72,15 +72,15 @@ public class ProcessTest {
// 2 assert that we cannot make another Process in the same JVM
try {
- process = new TestProcess(null);
+ process = new TestProcess(props);
fail();
} catch (IllegalStateException e) {
assertThat(e.getMessage()).isEqualTo("Process already exists in current JVM");
}
}
- @Test
- public void should_stop() throws Exception {
+ @Test(timeout = 5000L)
+ public void should_stop_explicit() throws Exception {
Properties properties = new Properties();
properties.setProperty(Process.NAME_PROPERTY, "TEST");
Props props = Props.create(properties);
@@ -107,19 +107,18 @@ public class ProcessTest {
// 2. Stop the process through Management
processMXBean.stop();
- Thread.sleep(200);
- assertThat(procThread.isAlive()).isFalse();
+ procThread.join();
}
@Test(timeout = 5000L)
- public void should_stop_by_itself() throws Exception {
+ public void should_stop_implicit() throws Exception {
Properties properties = new Properties();
properties.setProperty(Process.NAME_PROPERTY, "TEST");
properties.setProperty(Process.PORT_PROPERTY, Integer.toString(freePort));
Props props = Props.create(properties);
process = new TestProcess(props);
- process.start();
+ process.start();
}
public static class TestProcess extends Process {
@@ -137,7 +136,7 @@ public class ProcessTest {
ready = true;
while (running) {
try {
- Thread.sleep(200);
+ Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}