Skip to content

Commit

Permalink
Log exceptions from tasks in IdleTaskManager.
Browse files Browse the repository at this point in the history
Otherwise they are lost, making debugging very difficult.

PiperOrigin-RevId: 679540076
Change-Id: I4000ad55745578b0cd8d5c2cc9766e5c7f18059d
  • Loading branch information
tjgq authored and copybara-github committed Sep 27, 2024
1 parent de2a103 commit 1b9870e
Showing 1 changed file with 23 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
* Runs cleanup-related tasks during an idle period in the server.
Expand Down Expand Up @@ -61,6 +66,8 @@ private enum State {
private final ImmutableList<IdleTask> registeredTasks;
private final boolean stateKeptAfterBuild;

private final ArrayList<ScheduledFuture<?>> taskFutures = new ArrayList<>();

/**
* Creates a new {@link IdleTaskManager}.
*
Expand All @@ -83,19 +90,19 @@ public synchronized void idle() {

// Schedule tasks in the order they were registered.
for (IdleTask task : registeredTasks) {
var unused = executor.schedule(task::run, task.delay().toSeconds(), TimeUnit.SECONDS);
taskFutures.add(executor.schedule(task::run, task.delay().toSeconds(), TimeUnit.SECONDS));
}

// Schedule the final task to run after everything else.
// Note that this is effectively enforced by the fact that the executor is single-threaded and
// executes tasks in the order they are scheduled.
var unused =
taskFutures.add(
executor.schedule(
() -> runGcAndMaybeShrinkInterners(stateKeptAfterBuild),
// If state was kept after the build, wait for a few seconds before triggering GC, to
// avoid unnecessarily slowing down an immediately following incremental build.
stateKeptAfterBuild ? 10 : 0,
TimeUnit.SECONDS);
TimeUnit.SECONDS));
}

/**
Expand All @@ -122,6 +129,19 @@ public synchronized void busy() {
}
}

for (ScheduledFuture<?> taskFuture : taskFutures) {
try {
taskFuture.get(0, TimeUnit.SECONDS);
} catch (ExecutionException e) {
logger.atWarning().withCause(e.getCause()).log("Unexpected exception from idle task");
} catch (TimeoutException | CancellationException e) {
// Expected if the task hadn't yet started running or was interrupted mid-run.
} catch (InterruptedException e) {
// We ourselves were interrupted, not the task.
interrupted = true;
}
}

if (interrupted) {
Thread.currentThread().interrupt();
}
Expand Down

0 comments on commit 1b9870e

Please sign in to comment.