Skip to content

Commit

Permalink
[LaraFramework] Improves output of WeaverLauncher.executeParallel()
Browse files Browse the repository at this point in the history
- Besides a boolean indicating if execution was successful, now also
returns an exception if one was raised, and the arguments used for that
run;
  • Loading branch information
joaobispo committed Feb 5, 2024
1 parent 7c7ea78 commit a4f3e8e
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 14 deletions.
77 changes: 63 additions & 14 deletions LaraFramework/src/pt/up/fe/specs/lara/WeaverLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
package pt.up.fe.specs.lara;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
Expand All @@ -29,12 +32,16 @@

import org.lara.interpreter.joptions.config.interpreter.LaraiKeys;
import org.lara.interpreter.weaver.interf.WeaverEngine;
import org.openjdk.jmh.runner.RunnerException;

import com.google.gson.Gson;

import larai.LaraI;
import pt.up.fe.specs.lara.doc.LaraDocLauncher;
import pt.up.fe.specs.lara.unit.LaraUnitLauncher;
import pt.up.fe.specs.util.SpecsIo;
import pt.up.fe.specs.util.SpecsLogs;
import pt.up.fe.specs.util.SpecsStrings;
import pt.up.fe.specs.util.SpecsSystem;
import pt.up.fe.specs.util.utilities.CachedValue;

Expand Down Expand Up @@ -454,7 +461,7 @@ public String[] executeParallel(String[][] args, int threads, List<String> weave
var customThreadPool = threads > 0 ? new ForkJoinPool(threads) : new ForkJoinPool();

// Choose executor
Function<String[], Boolean> weaverExecutor = weaverCommand.isEmpty() ? this::executeSafe
Function<String[], WeaverResult> weaverExecutor = weaverCommand.isEmpty() ? this::executeSafe
: weaverArgs -> this.executeOtherJvm(weaverArgs, weaverCommand, workingFolder);

SpecsLogs.info("Launching " + args.length + " instances of weaver " + engine.getName()
Expand Down Expand Up @@ -487,7 +494,7 @@ public String[] executeParallel(String[][] args, int threads, List<String> weave
}

// Launch tasks
List<ForkJoinTask<Boolean>> tasks = new ArrayList<>();
List<ForkJoinTask<WeaverResult>> tasks = new ArrayList<>();
for (var weaverArgs : adaptedArgs) {
tasks.add(customThreadPool.submit(() -> weaverExecutor.apply(weaverArgs)));
}
Expand All @@ -497,7 +504,50 @@ public String[] executeParallel(String[][] args, int threads, List<String> weave

// Wait for tasks
for (var task : tasks) {
task.get();
var result = task.get();

var e = result.getException().orElse(null);

if (e == null) {
continue;
}

// If there is an exception, look for the results file and write an error json
try (StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter)) {

e.printStackTrace(printWriter);
var stackTrace = stringWriter.toString();

var taskArgs = result.getArgs();

// Get JSON results file
var indexOfR = taskArgs.length - 2;

if (taskArgs[indexOfR] != "-r") {
throw new RunnerException(
"Expected second to last argument to be '-r': " + Arrays.toString(taskArgs));
}

var resultsFile = taskArgs[indexOfR + 1];

var results = new LinkedHashMap<String, Object>();
var lastCause = SpecsSystem.getLastCause(e);
results.put("error", SpecsStrings.escapeJson(lastCause.getMessage()));
results.put("args", args);
results.put("stackTrace", SpecsStrings.escapeJson(stackTrace));

// var resultsReturn = new HashMap<>();
// // Must be inside an array
// resultsReturn.put("output", "[" + new Gson().toJson(results) + "]");

SpecsIo.write(new File(resultsFile), new Gson().toJson(results));

SpecsLogs.info("Exception during weaver execution:\n" + stackTrace);
} catch (Exception ex) {
SpecsLogs.info("Exception while retrieving error information: " + e);
ex.printStackTrace();
}
}

// Arrays.asList(adaptedArgs).stream()
Expand Down Expand Up @@ -538,24 +588,25 @@ private String[] collectResults(List<File> resultFiles) {
results.add("{}");
continue;
}

// System.out.println("CONTENTS:\n" + SpecsIo.read(resultFile));
results.add(SpecsIo.read(resultFile));
}

return results.toArray(size -> new String[size]);
}

private boolean executeSafe(String[] args) {
private WeaverResult executeSafe(String[] args) {
try {
// Create new WeaverEngine
var weaverEngineConstructor = getDefaultConstructor();
return new WeaverLauncher(weaverEngineConstructor.newInstance()).launch(args);
var weaverLauncher = new WeaverLauncher(weaverEngineConstructor.newInstance());
return new WeaverResult(args, weaverLauncher.launch(args));

} catch (Exception e) {
// throw new RuntimeException("Could not execute", e);
SpecsLogs.info("Exception during weaver execution: " + e);
e.printStackTrace();
return false;
// SpecsLogs.info("Exception during weaver execution: " + e);
// e.printStackTrace();
return new WeaverResult(args, e);
}
}

Expand All @@ -573,7 +624,7 @@ private Constructor<WeaverEngine> getDefaultConstructor() {
throw new RuntimeException("Could not find default constructor for WeaverEngine " + engine.getClass());
}

private boolean executeOtherJvm(String[] args, List<String> weaverCommand, File workingDir) {
private WeaverResult executeOtherJvm(String[] args, List<String> weaverCommand, File workingDir) {
try {
// DEBUG
// if (true) {
Expand All @@ -593,13 +644,11 @@ private boolean executeOtherJvm(String[] args, List<String> weaverCommand, File
// var result = SpecsSystem.run(newArgs, SpecsIo.getWorkingDir());
var result = SpecsSystem.run(newArgs, workingDir);

return result == 0;
return new WeaverResult(args, result == 0);

// return execute(args);
} catch (Exception e) {
SpecsLogs.info("Exception during weaver execution: " + e);
e.printStackTrace();
return false;
return new WeaverResult(args, e);
}
}

Expand Down
60 changes: 60 additions & 0 deletions LaraFramework/src/pt/up/fe/specs/lara/WeaverResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright 2024 SPeCS.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. under the License.
*/

package pt.up.fe.specs.lara;

import java.util.Optional;

public class WeaverResult {

private final boolean isSuccess;
private final String[] args;
private final Exception exception;

private WeaverResult(String[] args, boolean isSuccess, Exception exception) {
this.args = args;
this.isSuccess = isSuccess;
this.exception = exception;
}

/**
* For executions without exception.
*
* @param isSuccess
*/
public WeaverResult(String[] args, boolean isSuccess) {
this(args, isSuccess, null);
}

/**
* Unsuccessful execution with exception.
*
* @param e
*/
public WeaverResult(String[] args, Exception e) {
this(args, false, e);
}

public boolean isSuccess() {
return isSuccess;
}

public String[] getArgs() {
return args;
}

public Optional<Exception> getException() {
return Optional.ofNullable(exception);
}

}

0 comments on commit a4f3e8e

Please sign in to comment.