From b6d22a1cb733d3357a976917a45f0bf82a555f3c Mon Sep 17 00:00:00 2001 From: Stephane Gamard Date: Tue, 15 Jul 2014 19:00:23 +0200 Subject: [PATCH] SONAR-5409 - Using scheduler for Process parent ping-check --- .../main/java/org/sonar/process/Process.java | 69 ++++++++----------- .../java/org/sonar/process/ProcessTest.java | 15 ++-- 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(); } -- 2.39.5