From a3c488b79b1e5493499d174cf8e0cb5450038e83 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 26 May 2020 09:13:54 +0200 Subject: [PATCH] javac idle processes cleanup IDEA-CR-62977 GitOrigin-RevId: 0b6e9c23b08571817ed569f74a5ad68c03f2c6bc --- .../jps/incremental/java/JavaBuilder.java | 4 ++ .../jps/javac/ExternalJavacManager.java | 52 ++++++++++--------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 8d7295fbcb68..43fb2409494a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -1100,6 +1100,10 @@ public class JavaBuilder extends ModuleLevelBuilder { @Override public void chunkBuildFinished(CompileContext context, ModuleChunk chunk) { JavaBuilderUtil.cleanupChunkResources(context); + ExternalJavacManager extJavacManager = ExternalJavacManager.KEY.get(context); + if (extJavacManager != null) { + extJavacManager.shutdownIdleProcesses(); + } } private static Map> buildOutputDirectoriesMap(CompileContext context, ModuleChunk chunk) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalJavacManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalJavacManager.java index 1ad56ebccf15..d79a25a62803 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalJavacManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/ExternalJavacManager.java @@ -40,6 +40,8 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; public class ExternalJavacManager extends ProcessAdapter { @@ -205,9 +207,7 @@ public class ExternalJavacManager extends ProcessAdapter { } private ExternalJavacProcessHandler findRunningProcess(int processHash) { - if (LOG.isDebugEnabled()) { - LOG.debug("findRunningProcess: looking for hash " + processHash); - } + debug(()-> "findRunningProcess: looking for hash " + processHash); List idleProcesses = null; try { synchronized (myRunningProcesses) { @@ -220,25 +220,19 @@ public class ExternalJavacManager extends ProcessAdapter { final Integer hash = PROCESS_HASH.get(process); if (hash != null && hash == processHash && process.lock()) { - if (LOG.isDebugEnabled()) { - LOG.debug("findRunningProcess: returning process " + process.getProcessId() + " for hash " + processHash); - } + debug(()-> "findRunningProcess: returning process " + process.getProcessId() + " for hash " + processHash); return process; } if (process.getIdleTime() > myKeepAliveTimeout) { if (idleProcesses == null) { idleProcesses = new ArrayList<>(); } - if (LOG.isDebugEnabled()) { - LOG.debug("findRunningProcess: adding " + process.getProcessId() + " to idle list"); - } + debug(()-> "findRunningProcess: adding " + process.getProcessId() + " to idle list"); idleProcesses.add(process); } } } - if (LOG.isDebugEnabled()) { - LOG.debug("findRunningProcess: no running process for " + processHash + " is found"); - } + debug(()-> "findRunningProcess: no running process for " + processHash + " is found"); return null; } finally { @@ -250,6 +244,18 @@ public class ExternalJavacManager extends ProcessAdapter { } } + private static void debug(T data, Function message) { + if (LOG.isDebugEnabled()) { + LOG.debug(message.apply(data)); + } + } + + private static void debug(Supplier message) { + if (LOG.isDebugEnabled()) { + LOG.debug(message.get()); + } + } + private static int processHash(String sdkHomePath, List vmOptions, JavaCompilingTool tool) { return Objects.hash(sdkHomePath.replace(File.separatorChar, '/'), vmOptions, tool.getId()); } @@ -304,10 +310,10 @@ public class ExternalJavacManager extends ProcessAdapter { private boolean shutdownProcess(ExternalJavacProcessHandler process) { UUID processId = process.getProcessId(); - LOG.debug("shutdownProcess: shutting down " + processId); + debug(()-> "shutdownProcess: shutting down " + processId); final Channel conn = myConnections.get(processId); if (conn != null && process.lock()) { - LOG.debug("shutdownProcess: sending shutdown request to " + processId); + debug(()-> "shutdownProcess: sending shutdown request to " + processId); conn.writeAndFlush(JavacProtoUtil.toMessage(processId, JavacProtoUtil.createShutdownRequest())); return true; } @@ -374,9 +380,7 @@ public class ExternalJavacManager extends ProcessAdapter { appendParam(cmdLine, FileUtil.toSystemIndependentName(workingDir.getPath())); - if (LOG.isDebugEnabled()) { - LOG.debug("starting external compiler: " + cmdLine); - } + debug(()-> "starting external compiler: " + cmdLine); FileUtil.createDirectory(workingDir); final int processHash = processHash(sdkHomePath, vmOptions, compilingTool); @@ -384,7 +388,7 @@ public class ExternalJavacManager extends ProcessAdapter { PROCESS_HASH.set(processHandler, processHash); processHandler.lock(); myRunningProcesses.put(processId, processHandler); - LOG.debug("external compiler process registered: id=" + processId + ", hash=" + processHash); + debug(()-> "external compiler process registered: id=" + processId + ", hash=" + processHash); processHandler.addProcessListener(this); processHandler.startNotify(); return processHandler; @@ -393,7 +397,7 @@ public class ExternalJavacManager extends ProcessAdapter { @Override public void processTerminated(@NotNull ProcessEvent event) { final UUID processId = ((ExternalJavacProcessHandler)event.getProcessHandler()).getProcessId(); - LOG.debug("process " + processId + " terminated"); + debug(()-> "process " + processId + " terminated"); myRunningProcesses.remove(processId); if (myConnections.get(processId) == null) { // only if connection has never been established @@ -596,10 +600,10 @@ public class ExternalJavacManager extends ProcessAdapter { Channel channel = null; synchronized (myConnections) { channel = myConnections.get(processId); - LOG.debug("lookupChannel: channel for " + processId + " is " + channel); + debug(channel, ch-> "lookupChannel: channel for " + processId + " is " + ch); while (channel == null) { if (!myRunningProcesses.containsKey(processId)) { - LOG.debug("lookupChannel: no process for " + processId); + debug(()-> "lookupChannel: no process for " + processId); break; // the process is already gone } try { @@ -608,7 +612,7 @@ public class ExternalJavacManager extends ProcessAdapter { catch (InterruptedException ignored) { } channel = myConnections.get(processId); - LOG.debug("lookupChannel: after wait channel for " + processId + " is " + channel); + debug(channel, ch-> "lookupChannel: after wait channel for " + processId + " is " + ch); } } return channel; @@ -710,7 +714,7 @@ public class ExternalJavacManager extends ProcessAdapter { } boolean successfully = isTerminatedSuccessfully(); if (!successfully) { - LOG.debug("Javac compile session " + myId + " in process " + myProcessId + "didn't terminate successfully"); + debug(()-> "Javac compile session " + myId + " in process " + myProcessId + "didn't terminate successfully"); } return successfully; } @@ -725,7 +729,7 @@ public class ExternalJavacManager extends ProcessAdapter { } boolean successfully = isTerminatedSuccessfully(); if (!successfully) { - LOG.debug("Javac compile session " + myId + " in process " + myProcessId + "didn't terminate successfully"); + debug(()-> "Javac compile session " + myId + " in process " + myProcessId + "didn't terminate successfully"); } return successfully; }