* <li>First byte contains {@link #EMPTY} until process is UP and writes {@link #UP}</li>
* <li>Second byte contains {@link #EMPTY} until any process requests current one to stop by writing value {@link #STOP}</li>
* <li>Third byte contains {@link #EMPTY} until any process requests current one to restart by writing value {@link #RESTART}. Process acknowledges restart by writing back {@link #EMPTY}</li>
+ * <li>Fourth byte will always contain {@link #EMPTY} unless process declares that it is operational by writing {@link #OPERATIONAL}. This does not imply that is done starting.</li>
* <li>The next 8 bytes contains a long (value of {@link System#currentTimeMillis()}) which represents the date of the last ping</li>
* </ul>
* </p>
private static final int UP_BYTE_OFFSET = 0;
private static final int STOP_BYTE_OFFSET = 1;
private static final int RESTART_BYTE_OFFSET = 2;
- private static final int PING_BYTE_OFFSET = 3;
+ private static final int OPERATIONAL_BYTE_OFFSET = 3;
+ private static final int PING_BYTE_OFFSET = 4;
- private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 1 + 1 + 8;
+ private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 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;
private static final byte STOP = (byte) 0xFF;
private static final byte RESTART = (byte) 0xAA;
+ private static final byte OPERATIONAL = (byte) 0x59;
private static final byte UP = (byte) 0x01;
private static final byte EMPTY = (byte) 0x00;
writeByte(processNumber, UP_BYTE_OFFSET, UP);
}
+ boolean isOperational(int processNumber) {
+ return readByte(processNumber, OPERATIONAL_BYTE_OFFSET) == OPERATIONAL;
+ }
+
+ /**
+ * To be executed by child process to declare that it is started and fully operational
+ */
+ void setOperational(int processNumber) {
+ writeByte(processNumber, OPERATIONAL_BYTE_OFFSET, OPERATIONAL);
+ }
+
void ping(int processNumber) {
writeLong(processNumber, PING_BYTE_OFFSET, System.currentTimeMillis());
}
AllProcessesCommands.this.setUp(processNumber);
}
+ @Override
+ public boolean isOperational() {
+ return AllProcessesCommands.this.isOperational(processNumber);
+ }
+
+ @Override
+ public void setOperational() {
+ AllProcessesCommands.this.setOperational(processNumber);
+ }
+
@Override
public void ping() {
AllProcessesCommands.this.ping(processNumber);
package org.sonar.process;
import java.io.File;
+import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
private static final byte STOP = (byte) 0xFF;
private static final byte RESTART = (byte) 0xAA;
private static final byte UP = (byte) 0x01;
+ private static final byte OPERATIONAL = (byte) 0x59;
private static final byte EMPTY = (byte) 0x00;
@Rule
}
@Test
- public void child_process_update_the_mapped_memory() throws Exception {
- File dir = temp.newFolder();
+ public void write_and_read_up() throws IOException {
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 0;
- AllProcessesCommands commands = new AllProcessesCommands(dir);
assertThat(commands.isUp(PROCESS_NUMBER)).isFalse();
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER))).isEqualTo(EMPTY);
- assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset(PROCESS_NUMBER))).isEqualTo(0L);
+ assertThat(readByte(commands, offset)).isEqualTo(EMPTY);
commands.setUp(PROCESS_NUMBER);
assertThat(commands.isUp(PROCESS_NUMBER)).isTrue();
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER))).isEqualTo(UP);
+ assertThat(readByte(commands, offset)).isEqualTo(UP);
+ }
+
+ @Test
+ public void write_and_read_operational() throws IOException {
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 3;
+
+ assertThat(commands.isOperational(PROCESS_NUMBER)).isFalse();
+ assertThat(readByte(commands, offset)).isEqualTo(EMPTY);
+
+ commands.setOperational(PROCESS_NUMBER);
+ assertThat(commands.isOperational(PROCESS_NUMBER)).isTrue();
+ assertThat(readByte(commands, offset)).isEqualTo(OPERATIONAL);
+ }
+
+ @Test
+ public void write_and_read_ping() throws IOException {
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+
+ int offset = 4;
+ assertThat(readLong(commands, offset)).isEqualTo(0L);
long currentTime = System.currentTimeMillis();
commands.ping(PROCESS_NUMBER);
- assertThat(commands.mappedByteBuffer.getLong(3 + commands.offset(PROCESS_NUMBER))).isGreaterThanOrEqualTo(currentTime);
+ assertThat(readLong(commands, offset)).isGreaterThanOrEqualTo(currentTime);
}
@Test
public void ask_for_stop() throws Exception {
- File dir = temp.newFolder();
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 1;
- AllProcessesCommands commands = new AllProcessesCommands(dir);
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 1)).isNotEqualTo(STOP);
+ assertThat(readByte(commands, offset)).isNotEqualTo(STOP);
assertThat(commands.askedForStop(PROCESS_NUMBER)).isFalse();
commands.askForStop(PROCESS_NUMBER);
assertThat(commands.askedForStop(PROCESS_NUMBER)).isTrue();
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 1)).isEqualTo(STOP);
+ assertThat(readByte(commands, offset)).isEqualTo(STOP);
}
@Test
public void ask_for_restart() throws Exception {
- File dir = temp.newFolder();
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 2;
- AllProcessesCommands commands = new AllProcessesCommands(dir);
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) +2)).isNotEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isNotEqualTo(RESTART);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isFalse();
commands.askForRestart(PROCESS_NUMBER);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isTrue();
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 2)).isEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isEqualTo(RESTART);
}
@Test
public void acknowledgeAskForRestart_has_no_effect_when_no_restart_asked() throws Exception {
- File dir = temp.newFolder();
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 2;
- AllProcessesCommands commands = new AllProcessesCommands(dir);
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 2)).isNotEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isNotEqualTo(RESTART);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isFalse();
commands.acknowledgeAskForRestart(PROCESS_NUMBER);
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 2)).isNotEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isNotEqualTo(RESTART);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isFalse();
}
@Test
public void acknowledgeAskForRestart_resets_askForRestart_has_no_effect_when_no_restart_asked() throws Exception {
- File dir = temp.newFolder();
-
- AllProcessesCommands commands = new AllProcessesCommands(dir);
+ AllProcessesCommands commands = new AllProcessesCommands(temp.newFolder());
+ int offset = 2;
commands.askForRestart(PROCESS_NUMBER);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isTrue();
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 2)).isEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isEqualTo(RESTART);
commands.acknowledgeAskForRestart(PROCESS_NUMBER);
- assertThat(commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + 2)).isNotEqualTo(RESTART);
+ assertThat(readByte(commands, offset)).isNotEqualTo(RESTART);
assertThat(commands.askedForRestart(PROCESS_NUMBER)).isFalse();
}
@Test
public void getProcessCommands_fails_if_processNumber_is_less_than_0() throws Exception {
- File dir = temp.newFolder();
+ AllProcessesCommands allProcessesCommands = new AllProcessesCommands(temp.newFolder());
int processNumber = -2;
- AllProcessesCommands allProcessesCommands = new AllProcessesCommands(dir);
-
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Process number " + processNumber + " is not valid");
@Test
public void getProcessCommands_fails_if_processNumber_is_higher_than_MAX_PROCESSES() throws Exception {
- File dir = temp.newFolder();
+ AllProcessesCommands allProcessesCommands = new AllProcessesCommands(temp.newFolder());
int processNumber = MAX_PROCESSES + 1;
- AllProcessesCommands allProcessesCommands = new AllProcessesCommands(dir);
-
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Process number " + processNumber + " is not valid");
allProcessesCommands.createAfterClean(processNumber);
}
+
+ private byte readByte(AllProcessesCommands commands, int offset) {
+ return commands.mappedByteBuffer.get(commands.offset(PROCESS_NUMBER) + offset);
+ }
+
+ private long readLong(AllProcessesCommands commands, int offset) {
+ return commands.mappedByteBuffer.getLong(offset + commands.offset(PROCESS_NUMBER));
+ }
}