diff --git a/agent/src/main/java/com/teamscale/jacoco/agent/PreMain.java b/agent/src/main/java/com/teamscale/jacoco/agent/PreMain.java index e72adc301..f1154b1d3 100644 --- a/agent/src/main/java/com/teamscale/jacoco/agent/PreMain.java +++ b/agent/src/main/java/com/teamscale/jacoco/agent/PreMain.java @@ -1,7 +1,6 @@ package com.teamscale.jacoco.agent; import com.teamscale.client.HttpUtils; -import com.teamscale.client.TeamscaleServer; import com.teamscale.jacoco.agent.configuration.AgentOptionReceiveException; import com.teamscale.jacoco.agent.logging.LogToTeamscaleAppender; import com.teamscale.jacoco.agent.options.AgentOptionParseException; @@ -13,7 +12,6 @@ import com.teamscale.jacoco.agent.options.TeamscalePropertiesUtils; import com.teamscale.jacoco.agent.testimpact.TestwiseCoverageAgent; import com.teamscale.jacoco.agent.upload.UploaderException; -import com.teamscale.jacoco.agent.upload.teamscale.TeamscaleConfig; import com.teamscale.jacoco.agent.util.AgentUtils; import com.teamscale.jacoco.agent.logging.DebugLogDirectoryPropertyDefiner; import com.teamscale.jacoco.agent.logging.LogDirectoryPropertyDefiner; diff --git a/agent/src/main/java/com/teamscale/jacoco/agent/logging/LogToTeamscaleAppender.java b/agent/src/main/java/com/teamscale/jacoco/agent/logging/LogToTeamscaleAppender.java index 53bf34e24..5b9ce0ca5 100644 --- a/agent/src/main/java/com/teamscale/jacoco/agent/logging/LogToTeamscaleAppender.java +++ b/agent/src/main/java/com/teamscale/jacoco/agent/logging/LogToTeamscaleAppender.java @@ -8,11 +8,13 @@ import com.teamscale.client.TeamscaleClient; import com.teamscale.jacoco.agent.options.AgentOptions; import org.checkerframework.checker.nullness.qual.Nullable; +import org.conqat.lib.commons.collections.IdentityHashSet; import retrofit2.Call; import java.time.Duration; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.*; public class LogToTeamscaleAppender extends AppenderBase { @@ -35,6 +37,9 @@ public class LogToTeamscaleAppender extends AppenderBase { /** Scheduler for sending logs after the configured time interval */ private final ScheduledExecutorService scheduler; + /** Active log flushing threads */ + private final Set> activeLogFlushes = new IdentityHashSet<>(); + public LogToTeamscaleAppender() { this.scheduler = Executors.newScheduledThreadPool(1, r -> { // Make the thread a daemon so that it does not prevent the JVM from terminating. @@ -81,7 +86,7 @@ private void flush() { /** Send logs in a separate thread */ private void sendLogs(List logs) { - CompletableFuture.runAsync(() -> { + activeLogFlushes.add(CompletableFuture.runAsync(() -> { try { if (teamscaleClient == null) { // There might be no connection configured. @@ -96,7 +101,9 @@ private void sendLogs(List logs) { } catch (Exception e) { System.err.println("Sending logs to Teamscale failed: " + e.getMessage()); } - }); + }).whenComplete((result, throwable) -> { + activeLogFlushes.removeIf(CompletableFuture::isDone); + })); } @Override @@ -116,6 +123,9 @@ public void stop() { // A final flush after the scheduler has been shut down. flush(); + // Block until all flushes are done + CompletableFuture.allOf(activeLogFlushes.toArray(new CompletableFuture[0])).join(); + super.stop(); }