diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-09-22 22:56:07 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-09-22 22:56:07 +0200 |
commit | f00cda378e649a87b2b1693db5aaaec37461a481 (patch) | |
tree | eca8da0483f5e877cac3ed31d13e8af0f4703b8e /server/sonar-process/src | |
parent | 92c30ccd4cd311dc602c0e1a08fc97c09970a4f6 (diff) | |
download | sonarqube-f00cda378e649a87b2b1693db5aaaec37461a481.tar.gz sonarqube-f00cda378e649a87b2b1693db5aaaec37461a481.zip |
SONAR-4898 add sonar.enableStopCommand property for internal use
Diffstat (limited to 'server/sonar-process/src')
6 files changed, 64 insertions, 69 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java index 259af6b1eeb..417d62cb5bf 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java @@ -57,22 +57,19 @@ public class ProcessCommands { this.stopFile = stopFile; } - /** - * Executed by monitor - delete shared files before starting child process - */ - public void prepareMonitor() { + public void prepare() { deleteFile(readyFile); deleteFile(stopFile); } - public void finalizeProcess() { + public void endWatch() { // do not fail if files can't be deleted FileUtils.deleteQuietly(readyFile); FileUtils.deleteQuietly(stopFile); } - public boolean wasReadyAfter(long launchedAt) { - return isCreatedAfter(readyFile, launchedAt); + public boolean isReady() { + return readyFile.exists(); } /** @@ -89,8 +86,8 @@ public class ProcessCommands { createFile(stopFile); } - public boolean askedForStopAfter(long launchedAt) { - return isCreatedAfter(stopFile, launchedAt); + public boolean askedForStop() { + return stopFile.exists(); } File getReadyFile() { @@ -117,9 +114,4 @@ public class ProcessCommands { } } } - - private boolean isCreatedAfter(File file, long launchedAt) { - // File#lastModified() can have second precision on some OS - return file.exists() && file.lastModified() / 1000 >= launchedAt / 1000; - } } 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 f4d6e7f90f7..870f1aea067 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 @@ -21,7 +21,7 @@ package org.sonar.process; import org.slf4j.LoggerFactory; -public class ProcessEntryPoint { +public class ProcessEntryPoint implements Stoppable { public static final String PROPERTY_PROCESS_KEY = "process.key"; public static final String PROPERTY_TERMINATION_TIMEOUT = "process.terminationTimeout"; @@ -32,7 +32,6 @@ public class ProcessEntryPoint { private final ProcessCommands commands; private final SystemExit exit; private volatile Monitored monitored; - private volatile long launchedAt; private volatile StopperThread stopperThread; private final StopWatcher stopWatcher; @@ -49,7 +48,6 @@ public class ProcessEntryPoint { this.props = props; this.exit = exit; this.commands = commands; - this.launchedAt = System.currentTimeMillis(); this.stopWatcher = new StopWatcher(commands, this); } @@ -68,6 +66,7 @@ public class ProcessEntryPoint { if (!lifecycle.tryToMoveTo(Lifecycle.State.STARTING)) { throw new IllegalStateException("Already started"); } + commands.prepare(); monitored = mp; try { @@ -116,10 +115,12 @@ public class ProcessEntryPoint { exit.exit(0); } - void stopAsync() { + @Override + public void stopAsync() { if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) { stopperThread = new StopperThread(monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT))); stopperThread.start(); + stopWatcher.stopWatching(); } } @@ -131,10 +132,6 @@ public class ProcessEntryPoint { return shutdownHook; } - long getLaunchedAt() { - return launchedAt; - } - public static ProcessEntryPoint createForArguments(String[] args) { Props props = ConfigurationUtils.loadPropsFromCommandLineArgs(args); ProcessCommands commands = new ProcessCommands( diff --git a/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java index 090b0052423..b7b4ffa15d8 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java +++ b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java @@ -23,31 +23,35 @@ import org.slf4j.LoggerFactory; public class StopWatcher extends Thread { - private final ProcessEntryPoint process; + private final Stoppable stoppable; private final ProcessCommands commands; private boolean watching = true; - public StopWatcher(ProcessCommands commands, ProcessEntryPoint process) { + public StopWatcher(ProcessCommands commands, Stoppable stoppable) { super("Stop Watcher"); this.commands = commands; - this.process = process; + this.stoppable = stoppable; } @Override public void run() { - while (watching) { - if (commands.askedForStopAfter(process.getLaunchedAt())) { - LoggerFactory.getLogger(getClass()).info("Stopping process"); - process.stopAsync(); - watching = false; - } else { - try { - Thread.sleep(500L); - } catch (InterruptedException ignored) { + commands.prepare(); + try { + while (watching) { + if (commands.askedForStop()) { + LoggerFactory.getLogger(getClass()).info("Stopping process"); + stoppable.stopAsync(); watching = false; + } else { + try { + Thread.sleep(500L); + } catch (InterruptedException ignored) { + watching = false; + } } } - + } finally { + commands.endWatch(); } } diff --git a/server/sonar-process/src/main/java/org/sonar/process/Stoppable.java b/server/sonar-process/src/main/java/org/sonar/process/Stoppable.java new file mode 100644 index 00000000000..afd464a67a1 --- /dev/null +++ b/server/sonar-process/src/main/java/org/sonar/process/Stoppable.java @@ -0,0 +1,26 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.process; + +public interface Stoppable { + + void stopAsync(); + +} 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 317cd6f62c3..764d551a93c 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 @@ -57,6 +57,6 @@ class StopperThread extends Thread { LoggerFactory.getLogger(getClass()).error(String.format("Can not stop in %dms", terminationTimeout), e); } executor.shutdownNow(); - commands.finalizeProcess(); + commands.endWatch(); } } diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java index 49c8f024c69..e81a537e2ee 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java @@ -40,11 +40,11 @@ public class ProcessCommandsTest { public void delete_files_on_monitor_startup() throws Exception { File dir = temp.newFolder(); assertThat(dir).exists(); - FileUtils.touch(new File(dir, "WEB.ready")); - FileUtils.touch(new File(dir, "WEB.stop")); + FileUtils.touch(new File(dir, "web.ready")); + FileUtils.touch(new File(dir, "web.stop")); - ProcessCommands commands = new ProcessCommands(dir, "WEB"); - commands.prepareMonitor(); + ProcessCommands commands = new ProcessCommands(dir, "web"); + commands.prepare(); assertThat(commands.getReadyFile()).doesNotExist(); assertThat(commands.getStopFile()).doesNotExist(); @@ -58,7 +58,7 @@ public class ProcessCommandsTest { ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile()); try { - commands.prepareMonitor(); + commands.prepare(); fail(); } catch (MessageException e) { // ok @@ -70,39 +70,15 @@ public class ProcessCommandsTest { File readyFile = temp.newFile(); ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile()); - commands.prepareMonitor(); + commands.prepare(); + assertThat(commands.isReady()).isFalse(); assertThat(readyFile).doesNotExist(); commands.setReady(); + assertThat(commands.isReady()).isTrue(); assertThat(readyFile).exists(); - commands.finalizeProcess(); + commands.endWatch(); assertThat(readyFile).doesNotExist(); } - - @Test - public void was_ready_after_date() throws Exception { - File readyFile = mock(File.class); - ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile()); - - // does not exist - when(readyFile.exists()).thenReturn(false); - when(readyFile.lastModified()).thenReturn(123456L); - assertThat(commands.wasReadyAfter(122000L)).isFalse(); - - // readyFile created before - when(readyFile.exists()).thenReturn(true); - when(readyFile.lastModified()).thenReturn(123456L); - assertThat(commands.wasReadyAfter(124000L)).isFalse(); - - // readyFile created after - when(readyFile.exists()).thenReturn(true); - when(readyFile.lastModified()).thenReturn(123456L); - assertThat(commands.wasReadyAfter(123123L)).isTrue(); - - // readyFile created after, but can be truncated to second on some OS - when(readyFile.exists()).thenReturn(true); - when(readyFile.lastModified()).thenReturn(123000L); - assertThat(commands.wasReadyAfter(123456L)).isTrue(); - } } |