and out of HardStopperThread & HardStopWatcher this simplifies responsibilities and duplicate (ineffective) closing of the shared memorytags/7.8
@@ -45,24 +45,20 @@ public class HardStopWatcher extends Thread { | |||
@Override | |||
public void run() { | |||
try { | |||
while (watching) { | |||
if (commands.askedForHardStop()) { | |||
LoggerFactory.getLogger(getClass()).info("Hard stopping process"); | |||
stoppable.hardStopAsync(); | |||
while (watching) { | |||
if (commands.askedForHardStop()) { | |||
LoggerFactory.getLogger(getClass()).info("Hard stopping process"); | |||
stoppable.hardStopAsync(); | |||
watching = false; | |||
} else { | |||
try { | |||
Thread.sleep(delayMs); | |||
} catch (InterruptedException ignored) { | |||
watching = false; | |||
} else { | |||
try { | |||
Thread.sleep(delayMs); | |||
} catch (InterruptedException ignored) { | |||
watching = false; | |||
// restore interrupted flag | |||
Thread.currentThread().interrupt(); | |||
} | |||
// restore interrupted flag | |||
Thread.currentThread().interrupt(); | |||
} | |||
} | |||
} finally { | |||
commands.endWatch(); | |||
} | |||
} | |||
@@ -19,13 +19,11 @@ | |||
*/ | |||
package org.sonar.process; | |||
import org.slf4j.LoggerFactory; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import java.util.concurrent.Future; | |||
import java.util.concurrent.TimeUnit; | |||
import org.sonar.process.sharedmemoryfile.ProcessCommands; | |||
import org.slf4j.LoggerFactory; | |||
/** | |||
* Stops process in a short time fashion | |||
@@ -34,13 +32,11 @@ class HardStopperThread extends Thread { | |||
private final Monitored monitored; | |||
private final long terminationTimeoutMs; | |||
private final ProcessCommands commands; | |||
HardStopperThread(Monitored monitored, ProcessCommands commands, long terminationTimeoutMs) { | |||
HardStopperThread(Monitored monitored, long terminationTimeoutMs) { | |||
super("HardStopper"); | |||
this.monitored = monitored; | |||
this.terminationTimeoutMs = terminationTimeoutMs; | |||
this.commands = commands; | |||
} | |||
@Override | |||
@@ -53,6 +49,5 @@ class HardStopperThread extends Thread { | |||
LoggerFactory.getLogger(getClass()).error("Can not stop in {}ms", terminationTimeoutMs, e); | |||
} | |||
executor.shutdownNow(); | |||
commands.endWatch(); | |||
} | |||
} |
@@ -165,13 +165,15 @@ public class ProcessEntryPoint implements Stoppable { | |||
} catch (InterruptedException e) { | |||
Thread.currentThread().interrupt(); | |||
} | |||
commands.endWatch(); | |||
exit.exit(0); | |||
} | |||
@Override | |||
public void hardStopAsync() { | |||
if (lifecycle.tryToMoveTo(Lifecycle.State.HARD_STOPPING)) { | |||
hardStopperThread = new HardStopperThread(monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT_MS))); | |||
long terminationTimeoutMs = Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT_MS)); | |||
hardStopperThread = new HardStopperThread(monitored, terminationTimeoutMs); | |||
hardStopperThread.start(); | |||
hardStopWatcher.stopWatching(); | |||
} |
@@ -22,19 +22,20 @@ package org.sonar.process; | |||
import org.junit.Test; | |||
import org.mockito.invocation.InvocationOnMock; | |||
import org.mockito.stubbing.Answer; | |||
import org.sonar.process.sharedmemoryfile.ProcessCommands; | |||
import static org.mockito.Mockito.*; | |||
import static org.mockito.Mockito.doAnswer; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.timeout; | |||
import static org.mockito.Mockito.verify; | |||
public class HardStopperThreadTest { | |||
ProcessCommands commands = mock(ProcessCommands.class); | |||
Monitored monitored = mock(Monitored.class); | |||
private Monitored monitored = mock(Monitored.class); | |||
@Test | |||
public void stop_in_a_timely_fashion() { | |||
// max stop timeout is 5 seconds, but test fails after 3 seconds | |||
// -> guarantees that stop is immediate | |||
HardStopperThread stopper = new HardStopperThread(monitored, commands, 5000L); | |||
HardStopperThread stopper = new HardStopperThread(monitored, 5000L); | |||
stopper.start(); | |||
verify(monitored, timeout(3000)).hardStop(); | |||
@@ -51,7 +52,7 @@ public class HardStopperThreadTest { | |||
}).when(monitored).hardStop(); | |||
// max stop timeout is 100 milliseconds | |||
HardStopperThread stopper = new HardStopperThread(monitored, commands, 100L); | |||
HardStopperThread stopper = new HardStopperThread(monitored, 100L); | |||
stopper.start(); | |||
verify(monitored, timeout(3000)).hardStop(); |