Skip to content

Commit

Permalink
fixed race conditions, crudely but effectively. There must be a faste…
Browse files Browse the repository at this point in the history
…r solution using a concurrent list implementation
  • Loading branch information
jurgenvinju committed Apr 2, 2024
1 parent 40d71da commit e2c5714
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 49 deletions.
28 changes: 17 additions & 11 deletions src/org/rascalmpl/repl/TerminalProgressBarMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,21 @@ public TerminalProgressBarMonitor(OutputStream out, Terminal tm) {
* Represents one currently running progress bar
*/
private class ProgressBar {
private final long threadId;
private final String name;
private int max;
private int current = 0;
private int previousWidth = 0;
private int doneWidth = 0;
private int barWidth = lineWidth - "☐ ".length() - " 🕐 00:00:00.000 ".length();
private final int barWidth = lineWidth - "☐ ".length() - " 🕐 00:00:00.000 ".length();
private final Instant startTime;
private Duration duration;
private String message = "";
private int stepper = 0;
private final String[] clocks = new String[] {"🕐" , "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕛"};

ProgressBar(String name, int max) {
this.threadId = Thread.currentThread().getId();
this.name = name;
this.max = max;
this.startTime = Instant.now();
Expand Down Expand Up @@ -114,7 +116,6 @@ int newWidth() {
void write() {
previousWidth = doneWidth;
doneWidth = newWidth();


// var overWidth = barWidth - doneWidth;
var done = current >= max ? "☑ " : "☐ ";
Expand Down Expand Up @@ -156,12 +157,15 @@ else if (barWidth <= 3) { // we can print the clock for good measure

@Override
public boolean equals(Object obj) {
return obj instanceof ProgressBar && ((ProgressBar) obj).name.equals(name);
return obj instanceof ProgressBar
&& ((ProgressBar) obj).name.equals(name)
&& ((ProgressBar) obj).threadId == threadId
;
}

@Override
public int hashCode() {
return name.hashCode();
return name.hashCode() + 31 * (int) threadId;

Check warning on line 168 in src/org/rascalmpl/repl/TerminalProgressBarMonitor.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/repl/TerminalProgressBarMonitor.java#L168

Added line #L168 was not covered by tests
}

public void done() {
Expand Down Expand Up @@ -243,11 +247,13 @@ private void printBars() {
* @return the current instance by that name
*/
private ProgressBar findBarByName(String name) {
return bars.stream().filter(b -> b.name.equals(name)).findFirst().orElseGet(() -> null);
return bars.stream()
.filter(b -> b.threadId == Thread.currentThread().getId())
.filter(b -> b.name.equals(name)).findFirst().orElseGet(() -> null);
}

@Override
public void jobStart(String name, int workShare, int totalWork) {
public synchronized void jobStart(String name, int workShare, int totalWork) {
var pb = findBarByName(name);

eraseBars(); // to make room for the new bars
Expand All @@ -264,7 +270,7 @@ public void jobStart(String name, int workShare, int totalWork) {
}

@Override
public void jobStep(String name, String message, int workShare) {
public synchronized void jobStep(String name, String message, int workShare) {
ProgressBar pb = findBarByName(name);

if (pb != null) {
Expand All @@ -274,7 +280,7 @@ public void jobStep(String name, String message, int workShare) {
}

@Override
public int jobEnd(String name, boolean succeeded) {
public synchronized int jobEnd(String name, boolean succeeded) {
var pb = findBarByName(name);

if (pb != null) {
Expand All @@ -292,13 +298,13 @@ public int jobEnd(String name, boolean succeeded) {
}

@Override
public boolean jobIsCanceled(String name) {
public synchronized boolean jobIsCanceled(String name) {
// ? don't know what this should do
return false;

Check warning on line 303 in src/org/rascalmpl/repl/TerminalProgressBarMonitor.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/repl/TerminalProgressBarMonitor.java#L303

Added line #L303 was not covered by tests
}

@Override
public void jobTodo(String name, int work) {
public synchronized void jobTodo(String name, int work) {
ProgressBar pb = findBarByName(name);

if (pb != null) {
Expand All @@ -308,7 +314,7 @@ public void jobTodo(String name, int work) {
}

@Override
public void warning(String message, ISourceLocation src) {
public synchronized void warning(String message, ISourceLocation src) {
eraseBars();
writer.println(("[WARNING] " + src + ": " + message));
printBars();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,50 +241,60 @@ private boolean waitForRunSignal() {
}

private void processModules() {
String module;
try {
while ((module = modules.poll()) != null) {
try {
evaluator.doImport(new NullRascalMonitor(), module);
}
catch (Throwable e) {
synchronized(stdout) {
evaluator.warning("Could not import " + module + " for testing...", null);
evaluator.warning(e.getMessage(), null);
e.printStackTrace(evaluator.getOutPrinter());
}

// register a failing module to make sure we report failure later on.

Description testDesc = Description.createTestDescription(getClass(), module, new CompilationFailed() {
@Override
public Class<? extends Annotation> annotationType() {
return getClass();
}
});
evaluator.job("Importing test modules", 1, (jn) -> {
try {
String module;

while ((module = modules.poll()) != null) {
evaluator.jobTodo(jn, 1);

try {
evaluator.doImport(new NullRascalMonitor(), module);
}
catch (Throwable e) {
synchronized(stdout) {
evaluator.warning("Could not import " + module + " for testing...", null);
evaluator.warning(e.getMessage(), null);
e.printStackTrace(evaluator.getOutPrinter());
}

Check warning on line 259 in src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java#L254-L259

Added lines #L254 - L259 were not covered by tests

// register a failing module to make sure we report failure later on.

Description testDesc = Description.createTestDescription(getClass(), module, new CompilationFailed() {

Check warning on line 263 in src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java#L263

Added line #L263 was not covered by tests
@Override
public Class<? extends Annotation> annotationType() {
return getClass();

Check warning on line 266 in src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java#L266

Added line #L266 was not covered by tests
}
});

testModules.add(testDesc);
descriptions.add(testDesc);
testModules.add(testDesc);
descriptions.add(testDesc);

Check warning on line 271 in src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/test/infrastructure/RascalJUnitParallelRecursiveTestRunner.java#L270-L271

Added lines #L270 - L271 were not covered by tests

continue;
}
continue;
}
finally {
evaluator.jobStep(jn, module);
}

ModuleEnvironment moduleEnv = heap.getModule(module.replaceAll("\\\\",""));
if (!moduleEnv.getTests().isEmpty()) {
Description modDesc = Description.createSuiteDescription(module);
for (AbstractFunction f : moduleEnv.getTests()) {
modDesc.addChild(Description.createTestDescription(getClass(), RascalJUnitTestRunner.computeTestName(f.getName(), f.getAst().getLocation())));
ModuleEnvironment moduleEnv = heap.getModule(module.replaceAll("\\\\",""));
if (!moduleEnv.getTests().isEmpty()) {
Description modDesc = Description.createSuiteDescription(module);
for (AbstractFunction f : moduleEnv.getTests()) {
modDesc.addChild(Description.createTestDescription(getClass(), RascalJUnitTestRunner.computeTestName(f.getName(), f.getAst().getLocation())));
}
descriptions.add(modDesc);
testModules.add(modDesc);
}
descriptions.add(modDesc);
testModules.add(modDesc);
}
// let's shuffle them
Collections.shuffle(testModules);
}
// let's shuffle them
Collections.shuffle(testModules);
}
finally {
importsCompleted.release();
}
finally {
importsCompleted.release();
}

return true;
});
}

private void initializeEvaluator() {
Expand Down

0 comments on commit e2c5714

Please sign in to comment.