Skip to content

Commit

Permalink
Added an improved error reporting to the components on two levels: 1.…
Browse files Browse the repository at this point in the history
… in the single abstract component implementations and in the ComponentStarter. The latter checks whether the component can report errors and tries to call the report method in case of an error.
  • Loading branch information
MichaelRoeder committed Dec 8, 2023
1 parent 0843a1d commit df9b160
Show file tree
Hide file tree
Showing 11 changed files with 520 additions and 343 deletions.
40 changes: 28 additions & 12 deletions src/main/java/org/hobbit/core/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ private Commands() {
*/
public static final byte SYSTEM_READY_SIGNAL = 1;
/**
* The signal sent by the benchmark controller to indicate that the
* benchmark is ready.
* The signal sent by the benchmark controller to indicate that the benchmark is
* ready.
*/
public static final byte BENCHMARK_READY_SIGNAL = 2;
/**
Expand Down Expand Up @@ -64,23 +64,19 @@ private Commands() {

public static final byte BENCHMARK_FINISHED_SIGNAL = 11;
/**
* Command used to ask a docker managing component to start a certain
* container.
* Command used to ask a docker managing component to start a certain container.
* <p>
* The command is followed by a String containing the following JSON data:
* <br>
* The command is followed by a String containing the following JSON data: <br>
* <code>
* {<br>"image": "image-to-run",<br> "type": "system|benchmark",<br> "parent":"parent-container-id"<br>}
* </code>
* </p>
*/
public static final byte DOCKER_CONTAINER_START = 12;
/**
* Command used to ask a docker managing component to stop a certain
* container.
* Command used to ask a docker managing component to stop a certain container.
* <p>
* The command is followed by a String containing the following JSON data:
* <br>
* The command is followed by a String containing the following JSON data: <br>
* <code>
* {<br>"containerId": "container-to-stop"<br>}
* </code>
Expand All @@ -95,8 +91,27 @@ private Commands() {
public static final byte DOCKER_CONTAINER_TERMINATED = 16;

public static final byte START_BENCHMARK_SIGNAL = 17;

public static final byte REQUEST_SYSTEM_RESOURCES_USAGE = 18;
/**
* Command used to report an error that should be persisted as part of the
* experiment result data.
* <p>
* The command is followed by a String containing the following JSON data: <br>
* <code>
* {<br>"containerId": "container reporting the error",
* <br>"errorType": "IRI of the error type (optional)",
* <br>"label": "A string that can be used as short label of an error (optional, the error type label will be used as default)"
* <br>"description": "A string that can be used as a short description of an error (optional, the error type description will be used as default)"
* <br>"details": "A string that contains details about the error, e.g., a stack trace (optional)."
* <br>}
* </code>
* </p>
* <p>
* The {@link org.hobbit.core.data.ErrorData} class can be used to represent
* this data as Java object.</p>
*/
public static final byte REPORT_ERROR = 19;

private static final ImmutableMap<Byte, String> ID_TO_COMMAND_NAME_MAP = generateMap();

Expand All @@ -116,7 +131,8 @@ private static ImmutableMap<Byte, String> generateMap() {
}

/**
* Returns the name of the command if it is defined inside the {@link Commands} class or its id as String.
* Returns the name of the command if it is defined inside the {@link Commands}
* class or its id as String.
*
* @param command the command that should be transformed into a String
* @return the name of the command or its id if the name is not known
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,40 +156,38 @@ public void init() throws Exception {

@Override
public void run() throws Exception {
sendToCmdQueue(Commands.BENCHMARK_READY_SIGNAL);
// wait for the start signal
startBenchmarkMutex.acquire();
executeBenchmark();
try {
sendToCmdQueue(Commands.BENCHMARK_READY_SIGNAL);
// wait for the start signal
startBenchmarkMutex.acquire();
executeBenchmark();
} catch (Exception e) {
throw reportAndWrap(e);
}
}

protected abstract void executeBenchmark() throws Exception;

/**
* Creates the given number of data generators using the given image name
* and environment variables.
* Creates the given number of data generators using the given image name and
* environment variables.
*
* @param dataGeneratorImageName
* name of the data generator Docker image
* @param numberOfDataGenerators
* number of generators that should be created
* @param envVariables
* environment variables for the data generators
* @param dataGeneratorImageName name of the data generator Docker image
* @param numberOfDataGenerators number of generators that should be created
* @param envVariables environment variables for the data generators
*/
protected void createDataGenerators(String dataGeneratorImageName, int numberOfDataGenerators,
String[] envVariables) {
createGenerator(dataGeneratorImageName, numberOfDataGenerators, envVariables, dataGenContainerIds);
}

/**
* Creates the given number of task generators using the given image name
* and environment variables.
* Creates the given number of task generators using the given image name and
* environment variables.
*
* @param taskGeneratorImageName
* name of the task generator Docker image
* @param numberOfTaskGenerators
* number of generators that should be created
* @param envVariables
* environment variables for the task generators
* @param taskGeneratorImageName name of the task generator Docker image
* @param numberOfTaskGenerators number of generators that should be created
* @param envVariables environment variables for the task generators
*/
protected void createTaskGenerators(String taskGeneratorImageName, int numberOfTaskGenerators,
String[] envVariables) {
Expand All @@ -199,14 +197,10 @@ protected void createTaskGenerators(String taskGeneratorImageName, int numberOfT
/**
* Internal method for creating generator components.
*
* @param generatorImageName
* name of the generator Docker image
* @param numberOfGenerators
* number of generators that should be created
* @param envVariables
* environment variables for the task generators
* @param generatorIds
* set of generator container names
* @param generatorImageName name of the generator Docker image
* @param numberOfGenerators number of generators that should be created
* @param envVariables environment variables for the task generators
* @param generatorIds set of generator container names
*/
private void createGenerator(String generatorImageName, int numberOfGenerators, String[] envVariables,
Set<String> generatorIds) {
Expand All @@ -216,7 +210,8 @@ private void createGenerator(String generatorImageName, int numberOfGenerators,
// NOTE: Count only includes generators created within this method call.
variables[variables.length - 2] = Constants.GENERATOR_COUNT_KEY + "=" + numberOfGenerators;
for (int i = 0; i < numberOfGenerators; ++i) {
// At the start generatorIds is empty, and new generators are added to it immediately.
// At the start generatorIds is empty, and new generators are added to it
// immediately.
// Current size of that set is used to make IDs for new generators.
variables[variables.length - 1] = Constants.GENERATOR_ID_KEY + "=" + generatorIds.size();
containerId = createContainer(generatorImageName, variables);
Expand All @@ -234,10 +229,9 @@ private void createGenerator(String generatorImageName, int numberOfGenerators,
* Creates the evaluate module using the given image name and environment
* variables.
*
* @param evalModuleImageName
* name of the evaluation module image
* @param envVariables
* environment variables that should be given to the module
* @param evalModuleImageName name of the evaluation module image
* @param envVariables environment variables that should be given to the
* module
*/
protected void createEvaluationModule(String evalModuleImageName, String[] envVariables) {
envVariables = ArrayUtils.add(envVariables, Constants.HOBBIT_EXPERIMENT_URI_KEY + "=" + experimentUri);
Expand All @@ -263,10 +257,9 @@ protected void createEvaluationStorage() {
* Creates the evaluate storage using the given image name and environment
* variables.
*
* @param evalStorageImageName
* name of the evaluation storage image
* @param envVariables
* environment variables that should be given to the component
* @param evalStorageImageName name of the evaluation storage image
* @param envVariables environment variables that should be given to the
* component
*/
protected void createEvaluationStorage(String evalStorageImageName, String[] envVariables) {
evalStoreContainerId = createContainer(evalStorageImageName, Constants.CONTAINER_TYPE_DATABASE, envVariables);
Expand Down Expand Up @@ -353,13 +346,12 @@ protected void waitForTaskGenToFinish() {
}

/**
* This method waits for the benchmarked system to terminate or times out
* after the given amount of time (in milliseconds).
* This method waits for the benchmarked system to terminate or times out after
* the given amount of time (in milliseconds).
*
* @param maxWaitingTime
* maximum waiting time in milliseconds
* @return {@code true} if the system has been terminated or {@code false}
* if the method timed out
* @param maxWaitingTime maximum waiting time in milliseconds
* @return {@code true} if the system has been terminated or {@code false} if
* the method timed out
*/
protected boolean waitForSystemToFinish(long maxWaitingTime) {
LOGGER.debug("Waiting for the benchmarked system to finish.");
Expand Down Expand Up @@ -422,8 +414,7 @@ protected void waitForEvalComponentsToFinish() {
* Uses the given model as result model if the result model is
* <code>null</code>. Else, the two models are merged.
*
* @param resultModel
* the new result model
* @param resultModel the new result model
*/
protected void setResultModel(Model resultModel) {
try {
Expand All @@ -445,9 +436,9 @@ protected void setResultModel(Model resultModel) {

/**
* Generates a default model containing an error code and the benchmark
* parameters if no result model has been received from the evaluation
* module until now. If the model already has been received, the error is
* added to the existing model.
* parameters if no result model has been received from the evaluation module
* until now. If the model already has been received, the error is added to the
* existing model.
*/
protected void generateErrorResultModel() {
try {
Expand All @@ -469,8 +460,7 @@ protected void generateErrorResultModel() {
}

/**
* Adds the {@link #benchmarkParamModel} triples to the {@link #resultModel}
* .
* Adds the {@link #benchmarkParamModel} triples to the {@link #resultModel} .
*/
protected void addParametersToResultModel() {
try {
Expand All @@ -480,8 +470,7 @@ protected void addParametersToResultModel() {
}
try {
Resource experimentResource = resultModel.getResource(experimentUri);
StmtIterator iterator = benchmarkParamModel.listStatements(
HobbitExperiments.New, null, (RDFNode) null);
StmtIterator iterator = benchmarkParamModel.listStatements(HobbitExperiments.New, null, (RDFNode) null);
Statement statement;
while (iterator.hasNext()) {
statement = iterator.next();
Expand All @@ -495,8 +484,7 @@ protected void addParametersToResultModel() {
/**
* Sends the result RDF model to the platform controller.
*
* @param model
* model containing the results
* @param model model containing the results
*/
protected void sendResultModel(Model model) {
try {
Expand Down Expand Up @@ -558,14 +546,12 @@ public void receiveCommand(byte command, byte[] data) {
}

/**
* This method handles messages from the command bus containing the
* information that a container terminated. It checks whether the container
* belongs to the current benchmark and whether it has to react.
* This method handles messages from the command bus containing the information
* that a container terminated. It checks whether the container belongs to the
* current benchmark and whether it has to react.
*
* @param containerName
* the name of the terminated container
* @param exitCode
* the exit code of the terminated container
* @param containerName the name of the terminated container
* @param exitCode the exit code of the terminated container
*/
protected void containerTerminated(String containerName, int exitCode) {
if (dataGenContainerIds.contains(containerName)) {
Expand Down
Loading

0 comments on commit df9b160

Please sign in to comment.