Skip to content

Commit

Permalink
Pause should not leave open an ExecutorService, using common pool fix…
Browse files Browse the repository at this point in the history
…es the issue (close assertj#268)
  • Loading branch information
henri-tremblay committed Jul 2, 2022
1 parent 9dae1fa commit 88c4c22
Showing 1 changed file with 44 additions and 42 deletions.
86 changes: 44 additions & 42 deletions assertj-swing/src/main/java/org/assertj/swing/timing/Pause.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
import static org.assertj.core.util.Preconditions.checkNotNullOrEmpty;
import static org.assertj.swing.timing.Timeout.timeout;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Nonnull;

Expand All @@ -38,7 +39,6 @@
public final class Pause {
private static final Timeout DEFAULT_TIMEOUT = timeout();
private static final int SLEEP_INTERVAL = 10;
private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();

/**
* Waits until the given condition is satisfied.
Expand Down Expand Up @@ -76,36 +76,32 @@ public static void pause(@Nonnull Condition condition, @Nonnull Timeout timeout)
public static void pause(@Nonnull final Condition condition, final long timeout) {
checkNotNull(condition);
try {
Callable<Object> task = new Callable<Object>() {
@Override
public Object call() {
while (!Thread.currentThread().isInterrupted() && !condition.test()) {
pause();
}
return condition;
}
};
performPause(task, timeout, condition);
performPause(timeout, condition);
} finally {
condition.done();
}
}

private static void performPause(Callable<Object> task, long timeout, Object value) {
Future<Object> futureResult = EXECUTOR_SERVICE.submit(task);
private static void performPause(long timeout, Condition condition) {
AtomicBoolean cancelled = new AtomicBoolean(false);

Runnable runnable = () -> {
while (!cancelled.get() && !Thread.currentThread().isInterrupted() && !condition.test()) {
pause();
}
};
Future<Void> future = CompletableFuture.runAsync(runnable);
try {
futureResult.get(timeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
futureResult.cancel(true);
throw new WaitTimedOutError(String.format("Timed out waiting for %s",
new StandardRepresentation().toStringOf(value)));
} catch (InterruptedException e) {
e.printStackTrace();
future.get(timeout, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
cancelled.set(true);
throw new WaitTimedOutError("Timed out waiting for " + new StandardRepresentation().toStringOf(condition));
}
}

Expand Down Expand Up @@ -152,31 +148,37 @@ public static void pause(@Nonnull final Condition[] conditions, final long timeo
for (Condition condition : conditions) {
checkNotNull(condition);
}
Condition condition = allConditions(conditions);
try {
Callable<Object> task = new Callable<Object>() {
@Override
public Object call() {
while (!Thread.currentThread().isInterrupted() && !areSatisfied(conditions)) {
pause();
}
return conditions;
}
};
performPause(task, timeout, conditions);
performPause(timeout, condition);
} finally {
for (Condition condition : conditions) {
condition.done();
}
condition.done();
}
}

private static boolean areSatisfied(@Nonnull Condition[] conditions) {
for (Condition condition : conditions) {
if (!condition.test()) {
return false;
private static Condition allConditions(@Nonnull Condition[] conditions) {
String description = Stream.of(conditions)
.map(Condition::toString)
.collect(Collectors.joining("\n", "=>", ""));
return new Condition(description) {
@Override
public boolean test() {
for (Condition condition : conditions) {
if (!condition.test()) {
return false;
}
}
return true;
}
}
return true;

@Override
protected void done() {
for (Condition condition : conditions) {
condition.done();
}
}
};

}

/**
Expand Down

0 comments on commit 88c4c22

Please sign in to comment.