mirror of
https://github.com/apache/lucene.git
synced 2025-03-06 16:29:30 +00:00
Release memory for cancelled tasks earlier in TaskExecutor (#13609)
We can save some memory in failure scenarios here (and a tiny bit in every case) by moving our started flag to the `FutureTask` and using the callable outright. First of all, we save the wrapper callable, but that also allows us to just `set(null)` on cancellation instead of waiting for the task to run to set the `null`. In case we have longer running tasks executing and it would take a while to get to the cancelled tasks, this saves some memory and allows us to return from the method earlier.
This commit is contained in:
parent
c52ddd83bf
commit
b4a06770c9
@ -110,21 +110,23 @@ public final class TaskExecutor {
|
||||
}
|
||||
|
||||
RunnableFuture<T> createTask(Callable<T> callable) {
|
||||
AtomicBoolean startedOrCancelled = new AtomicBoolean(false);
|
||||
return new FutureTask<>(
|
||||
() -> {
|
||||
if (startedOrCancelled.compareAndSet(false, true)) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Throwable t) {
|
||||
cancelAll();
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
// task is cancelled hence it has no results to return. That's fine: they would be
|
||||
// ignored anyway.
|
||||
return null;
|
||||
}) {
|
||||
return new FutureTask<>(callable) {
|
||||
|
||||
private final AtomicBoolean startedOrCancelled = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (startedOrCancelled.compareAndSet(false, true)) {
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setException(Throwable t) {
|
||||
super.setException(t);
|
||||
cancelAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
assert mayInterruptIfRunning == false
|
||||
@ -136,7 +138,13 @@ public final class TaskExecutor {
|
||||
wait for them to finish instead of throwing CancellationException. A cleaner way would have been to override FutureTask#get and
|
||||
make it wait for cancelled tasks, but FutureTask#awaitDone is private. Tasks that are cancelled before they are started will be no-op.
|
||||
*/
|
||||
return startedOrCancelled.compareAndSet(false, true);
|
||||
if (startedOrCancelled.compareAndSet(false, true)) {
|
||||
// task is cancelled hence it has no results to return. That's fine: they would be
|
||||
// ignored anyway.
|
||||
set(null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user