Skip to content

Commit

Permalink
Make throttled output loop robust against exceptions (gradle#24575)
Browse files Browse the repository at this point in the history
Signed-off-by: Björn Kautler <Bjoern@Kautler.net>
  • Loading branch information
Vampire committed Jul 17, 2023
1 parent 44d2d4d commit f17579e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.gradle.internal.logging.events.OutputEventListener;
import org.gradle.internal.logging.events.UpdateNowEvent;
import org.gradle.internal.time.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -33,6 +35,8 @@
* Queue output events to be forwarded and schedule flush when time passed or if end of build is signalled.
*/
public class ThrottlingOutputEventListener implements OutputEventListener {
private static final Logger LOGGER = LoggerFactory.getLogger(ThrottlingOutputEventListener.class);

private final OutputEventListener listener;

private final ScheduledExecutorService executor;
Expand All @@ -58,7 +62,13 @@ private void scheduleUpdateNow() {
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
onOutput(new UpdateNowEvent(clock.getCurrentTime()));
try {
onOutput(new UpdateNowEvent(clock.getCurrentTime()));
} catch (Throwable t) {
// this class is used as task in a scheduled executor service, so it must not throw any throwable,
// otherwise the further invocations of this task get automatically and silently cancelled
LOGGER.debug("Exception while displaying output", t);
}
}
}, throttleMs, throttleMs, TimeUnit.MILLISECONDS);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.gradle.internal.logging.events.EndOutputEvent
import org.gradle.internal.logging.events.FlushOutputEvent
import org.gradle.internal.logging.events.OutputEventListener
import org.gradle.internal.logging.events.UpdateNowEvent
import org.gradle.internal.time.Clock
import org.gradle.internal.time.MockClock
import org.gradle.util.internal.MockExecutor
import spock.lang.Subject
Expand Down Expand Up @@ -155,4 +156,24 @@ class ThrottlingOutputEventListenerTest extends OutputSpecification {
then:
executor.isShutdown()
}

def "throwables are not propagated out of the run method of the output loop"() {
given:
def executor = new MockExecutor()
new ThrottlingOutputEventListener(listener, 100, executor, Mock(Clock))
def checks = executor.shutdownNow()

when:
checks*.run()

then:
1 * _ >> { throw throwable }
noExceptionThrown()

where:
throwable | _
new Exception() | _
new RuntimeException() | _
new Error() | _
}
}

0 comments on commit f17579e

Please sign in to comment.