Skip to content
Prev Previous commit
Next Next commit
Fix memory leak from cancelled timeout tasks in CopilotSession
Replace Executors.newSingleThreadScheduledExecutor with an explicit
ScheduledThreadPoolExecutor so we can enable removeOnCancelPolicy(true).
Without this, each call to sendAndWait() that completes normally cancels
its timeout task, but the cancelled task remains in the scheduler's work
queue, leaking memory over the lifetime of the session.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ed Burns <edburns@microsoft.com>
  • Loading branch information
edburns and Copilot committed Mar 27, 2026
commit 9e102bcba86fb156060a90c7ba0c0a87136953c7
5 changes: 4 additions & 1 deletion src/main/java/com/github/copilot/sdk/CopilotSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -159,11 +160,13 @@ public final class CopilotSession implements AutoCloseable {
this.sessionId = sessionId;
this.rpc = rpc;
this.workspacePath = workspacePath;
this.timeoutScheduler = Executors.newSingleThreadScheduledExecutor(r -> {
var executor = new ScheduledThreadPoolExecutor(1, r -> {
var t = new Thread(r, "sendAndWait-timeout");
t.setDaemon(true);
return t;
});
executor.setRemoveOnCancelPolicy(true);
this.timeoutScheduler = executor;
}

/**
Expand Down
Loading