]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7168 add restart request support to ProcessCommands
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 7 Jan 2016 11:26:08 +0000 (12:26 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 13 Jan 2016 10:45:51 +0000 (11:45 +0100)
server/sonar-process/src/main/java/org/sonar/process/DefaultProcessCommands.java
server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
server/sonar-process/src/test/java/org/sonar/process/DefaultProcessCommandsTest.java

index 72d6ca70560869dcb2e05f5417269911732c8952..3ceab37472e6c46e5471f6abb5eaa9526180c3b6 100644 (file)
@@ -56,17 +56,19 @@ public class DefaultProcessCommands implements ProcessCommands {
    * <ul>
    *   <li>First byte will contains the state 0x00 until READY 0x01</li>
    *   <li>The second byte will contains the request for stopping 0x00 or STOP (0xFF)</li>
+   *   <li>The second byte will contains the request for restarting 0x00 or RESTART (0xAA)</li>
    *   <li>The next 8 bytes contains a long (System.currentTimeInMillis for ping)</li>
    * </ul>
    */
   final MappedByteBuffer mappedByteBuffer;
   private final RandomAccessFile sharedMemory;
-  private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 1 + 8;
+  private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 1 + 1 + 8;
 
   // With this shared memory we can handle up to MAX_PROCESSES processes
   private static final int MAX_SHARED_MEMORY = BYTE_LENGTH_FOR_ONE_PROCESS * MAX_PROCESSES;
 
   public static final byte STOP = (byte) 0xFF;
+  public static final byte RESTART = (byte) 0xAA;
   public static final byte READY = (byte) 0x01;
   public static final byte EMPTY = (byte) 0x00;
 
@@ -135,6 +137,21 @@ public class DefaultProcessCommands implements ProcessCommands {
     return mappedByteBuffer.get(offset() + 1) == STOP;
   }
 
+  @Override
+  public void askForRestart() {
+    mappedByteBuffer.put(offset() + 3, RESTART);
+  }
+
+  @Override
+  public boolean askedForRestart() {
+    return mappedByteBuffer.get(offset() + 3) == RESTART;
+  }
+
+  @Override
+  public void acknowledgeAskForRestart() {
+    mappedByteBuffer.put(offset() + 3, EMPTY);
+  }
+
   @Override
   public void endWatch() {
     IOUtils.closeQuietly(sharedMemory);
index d6b0ef060182b5be3fd04e70f3822ad6f10ed624..789a4b8cefc4eabad198c0d21b1d9c425c8860c4 100644 (file)
@@ -24,6 +24,7 @@ package org.sonar.process;
  * <ul>
  *   <li>share status of child process</li>
  *   <li>stop child process</li>
+ *   <li>restart all child processes</li>
  * </ul>
  *
  * <p/>
@@ -57,5 +58,20 @@ public interface ProcessCommands {
 
   boolean askedForStop();
 
+  /**
+   * To be executed by child process to ask for restart of all child processes
+   */
+  void askForRestart();
+
+  /**
+   * Can be called by child or monitor process to know whether child process asked for restart
+   */
+  boolean askedForRestart();
+
+  /**
+   * To be executed by monitor process to acknowledge restart request from child process.
+   */
+  void acknowledgeAskForRestart();
+
   void endWatch();
 }
index 55aab7166b7ea5b5540bb7fc387768e8bb6ebf15..95a979b43098b64256a603a9e53930b2a73d5466 100644 (file)
@@ -52,6 +52,10 @@ public class ProcessEntryPoint implements Stoppable {
     this.stopWatcher = new StopWatcher(commands, this);
   }
 
+  public ProcessCommands getCommands() {
+    return commands;
+  }
+
   public Props getProps() {
     return props;
   }
index 763a22ad7d3ad7cefacf30a9885d925a8166241a..ee5f2f2124328268f0fd631c1f833264d8775b9e 100644 (file)
@@ -31,6 +31,8 @@ import static org.junit.Assert.fail;
 
 public class DefaultProcessCommandsTest {
 
+  private static final int PROCESS_NUMBER = 1;
+
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
@@ -40,7 +42,7 @@ public class DefaultProcessCommandsTest {
     FileUtils.deleteQuietly(dir);
 
     try {
-      new DefaultProcessCommands(dir, 1);
+      new DefaultProcessCommands(dir, PROCESS_NUMBER);
       fail();
     } catch (IllegalArgumentException e) {
       assertThat(e).hasMessage("Not a valid directory: " + dir.getAbsolutePath());
@@ -51,7 +53,7 @@ public class DefaultProcessCommandsTest {
   public void child_process_update_the_mapped_memory() throws Exception {
     File dir = temp.newFolder();
 
-    DefaultProcessCommands commands = new DefaultProcessCommands(dir, 1);
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, PROCESS_NUMBER);
     assertThat(commands.isReady()).isFalse();
     assertThat(commands.mappedByteBuffer.get(commands.offset())).isEqualTo(DefaultProcessCommands.EMPTY);
     assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset())).isEqualTo(0L);
@@ -69,13 +71,54 @@ public class DefaultProcessCommandsTest {
   public void ask_for_stop() throws Exception {
     File dir = temp.newFolder();
 
-    DefaultProcessCommands commands = new DefaultProcessCommands(dir, 1);
-    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isNotEqualTo(DefaultProcessCommands.STOP);
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, PROCESS_NUMBER);
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + PROCESS_NUMBER)).isNotEqualTo(DefaultProcessCommands.STOP);
     assertThat(commands.askedForStop()).isFalse();
 
     commands.askForStop();
     assertThat(commands.askedForStop()).isTrue();
-    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isEqualTo(DefaultProcessCommands.STOP);
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + PROCESS_NUMBER)).isEqualTo(DefaultProcessCommands.STOP);
+  }
+
+  @Test
+  public void ask_for_restart() throws Exception {
+    File dir = temp.newFolder();
+
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, PROCESS_NUMBER);
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isNotEqualTo(DefaultProcessCommands.RESTART);
+    assertThat(commands.askedForRestart()).isFalse();
+
+    commands.askForRestart();
+    assertThat(commands.askedForRestart()).isTrue();
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isEqualTo(DefaultProcessCommands.RESTART);
+  }
+
+  @Test
+  public void acknowledgeAskForRestart_has_no_effect_when_no_restart_asked() throws Exception {
+    File dir = temp.newFolder();
+
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, PROCESS_NUMBER);
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isNotEqualTo(DefaultProcessCommands.RESTART);
+    assertThat(commands.askedForRestart()).isFalse();
+
+    commands.acknowledgeAskForRestart();
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isNotEqualTo(DefaultProcessCommands.RESTART);
+    assertThat(commands.askedForRestart()).isFalse();
+  }
+
+  @Test
+  public void acknowledgeAskForRestart_resets_askForRestart_has_no_effect_when_no_restart_asked() throws Exception {
+    File dir = temp.newFolder();
+
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, PROCESS_NUMBER);
+
+    commands.askForRestart();
+    assertThat(commands.askedForRestart()).isTrue();
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isEqualTo(DefaultProcessCommands.RESTART);
+
+    commands.acknowledgeAskForRestart();
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 3)).isNotEqualTo(DefaultProcessCommands.RESTART);
+    assertThat(commands.askedForRestart()).isFalse();
   }
 
   @Test