mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
revert in-process compile server
This commit is contained in:
@@ -91,7 +91,7 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
private static final String COMPILE_SERVER_SYSTEM_ROOT = "compile-server";
|
||||
private static final String LOGGER_CONFIG = "log.xml";
|
||||
private static final String DEFAULT_LOGGER_CONFIG = "defaultLogConfig.xml";
|
||||
private volatile ServerWrapper myProcessHandler;
|
||||
private volatile OSProcessHandler myProcessHandler;
|
||||
private final File mySystemDirectory;
|
||||
@Nullable
|
||||
private volatile CompileServerClient myClient;
|
||||
@@ -335,7 +335,7 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
public RequestFuture submitCompilationTask(final Project project, final boolean isRebuild, final boolean isMake,
|
||||
final Collection<String> modules, final Collection<String> artifacts,
|
||||
final Collection<String> paths,
|
||||
final Map<String, String> _userData, final JpsServerResponseHandler handler) {
|
||||
final Map<String, String> userData, final JpsServerResponseHandler handler) {
|
||||
final String projectId = getProjectPath(project);
|
||||
final Ref<RequestFuture> futureRef = new Ref<RequestFuture>(null);
|
||||
final RunnableFuture future = myTaskExecutor.submit(new Runnable() {
|
||||
@@ -344,16 +344,9 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
try {
|
||||
final CompileServerClient client = ensureServerRunningAndClientConnected(true);
|
||||
if (client != null) {
|
||||
final Map<String, String> userData = new LinkedHashMap<String, String>();
|
||||
if (!isRebuild) { //todo pass user data on rebuild as well?
|
||||
userData.putAll(_userData);
|
||||
}
|
||||
if (Registry.is("compiler.server.use.external.javac.process")) {
|
||||
userData.put(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION, "true");
|
||||
}
|
||||
final RequestFuture requestFuture = isRebuild ?
|
||||
client.sendRebuildRequest(projectId, handler, userData) :
|
||||
client.sendCompileRequest(isMake, projectId, modules, artifacts, paths, userData, handler);
|
||||
client.sendRebuildRequest(projectId, handler, userData) :
|
||||
client.sendCompileRequest(isMake, projectId, modules, artifacts, paths, userData, handler);
|
||||
futureRef.set(requestFuture);
|
||||
}
|
||||
else {
|
||||
@@ -397,9 +390,9 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
// executed in one thread at a time
|
||||
@Nullable
|
||||
private CompileServerClient ensureServerRunningAndClientConnected(boolean forceRestart) throws Throwable {
|
||||
final ServerWrapper ph = myProcessHandler;
|
||||
final OSProcessHandler ph = myProcessHandler;
|
||||
final CompileServerClient cl = myClient;
|
||||
final boolean processNotRunning = ph == null || ph.isDead();
|
||||
final boolean processNotRunning = ph == null || ph.isProcessTerminated() || ph.isProcessTerminating();
|
||||
final boolean clientNotConnected = cl == null || !cl.isConnected();
|
||||
|
||||
if (processNotRunning || clientNotConnected) {
|
||||
@@ -412,13 +405,68 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
return null;
|
||||
}
|
||||
|
||||
final File workDirectory = new File(mySystemDirectory, COMPILE_SERVER_SYSTEM_ROOT);
|
||||
workDirectory.mkdirs();
|
||||
ensureLogConfigExists(workDirectory);
|
||||
|
||||
final int port = NetUtils.findAvailableSocketPort();
|
||||
final long serverPingInterval = Registry.intValue("compiler.server.ping.interval", -1) * 1000L;
|
||||
ServerWrapper wrapper = Registry.is("compiler.server.in.process") ? launchServerThread(workDirectory, port) : launchServerProcess(port, serverPingInterval, workDirectory);
|
||||
final long serverPingInterval = Registry.intValue("compiler.server.ping.interval", -1) * 1000L;
|
||||
final Process process = launchServer(port, serverPingInterval);
|
||||
|
||||
final OSProcessHandler processHandler = new OSProcessHandler(process, null) {
|
||||
@Override
|
||||
protected boolean shouldDestroyProcessRecursively() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final StringBuilder serverStartMessage = new StringBuilder();
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
// re-translate server's output to idea.log
|
||||
final String text = event.getText();
|
||||
if (!StringUtil.isEmpty(text)) {
|
||||
LOG.info("COMPILE_SERVER [" +outputType.toString() +"]: "+ text.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
try {
|
||||
processHandler.removeProcessListener(this);
|
||||
}
|
||||
finally {
|
||||
semaphore.up();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
if (outputType == ProcessOutputTypes.STDERR) {
|
||||
try {
|
||||
final String text = event.getText();
|
||||
if (text != null) {
|
||||
if (text.contains(Server.SERVER_SUCCESS_START_MESSAGE) || text.contains(Server.SERVER_ERROR_START_MESSAGE)) {
|
||||
processHandler.removeProcessListener(this);
|
||||
}
|
||||
if (serverStartMessage.length() > 0) {
|
||||
serverStartMessage.append("\n");
|
||||
}
|
||||
serverStartMessage.append(text);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
semaphore.up();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
processHandler.startNotify();
|
||||
semaphore.waitFor();
|
||||
|
||||
final String startupMsg = serverStartMessage.toString();
|
||||
if (!startupMsg.contains(Server.SERVER_SUCCESS_START_MESSAGE)) {
|
||||
throw new Exception("Server startup failed: " + startupMsg);
|
||||
}
|
||||
|
||||
CompileServerClient client = new CompileServerClient(serverPingInterval, myAsyncExec);
|
||||
boolean connected = false;
|
||||
@@ -427,90 +475,19 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
if (connected) {
|
||||
final RequestFuture setupFuture = sendSetupRequest(client);
|
||||
setupFuture.waitFor();
|
||||
myProcessHandler = wrapper;
|
||||
myProcessHandler = processHandler;
|
||||
myClient = client;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (!connected) {
|
||||
shutdownServer(cl, wrapper);
|
||||
shutdownServer(cl, processHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
return myClient;
|
||||
}
|
||||
|
||||
private static ServerWrapper launchServerThread(final File workDirectory, final int port) {
|
||||
final Server server = new Server(workDirectory, Registry.is("compiler.server.use.memory.temp.cache"));
|
||||
//todo hostname
|
||||
server.start(port);
|
||||
return new ServerWrapper(null, server);
|
||||
}
|
||||
|
||||
private ServerWrapper launchServerProcess(int port, long serverPingInterval, File workDirectory) throws Exception {
|
||||
final Process process = launchServer(port, serverPingInterval, workDirectory);
|
||||
|
||||
final OSProcessHandler processHandler = new OSProcessHandler(process, null) {
|
||||
@Override
|
||||
protected boolean shouldDestroyProcessRecursively() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final StringBuilder serverStartMessage = new StringBuilder();
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
// re-translate server's output to idea.log
|
||||
final String text = event.getText();
|
||||
if (!StringUtil.isEmpty(text)) {
|
||||
LOG.info("COMPILE_SERVER [" +outputType.toString() +"]: "+ text.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
try {
|
||||
processHandler.removeProcessListener(this);
|
||||
}
|
||||
finally {
|
||||
semaphore.up();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
if (outputType == ProcessOutputTypes.STDERR) {
|
||||
try {
|
||||
final String text = event.getText();
|
||||
if (text != null) {
|
||||
if (text.contains(Server.SERVER_SUCCESS_START_MESSAGE) || text.contains(Server.SERVER_ERROR_START_MESSAGE)) {
|
||||
processHandler.removeProcessListener(this);
|
||||
}
|
||||
if (serverStartMessage.length() > 0) {
|
||||
serverStartMessage.append("\n");
|
||||
}
|
||||
serverStartMessage.append(text);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
semaphore.up();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
processHandler.startNotify();
|
||||
semaphore.waitFor();
|
||||
|
||||
final String startupMsg = serverStartMessage.toString();
|
||||
if (!startupMsg.contains(Server.SERVER_SUCCESS_START_MESSAGE)) {
|
||||
throw new Exception("Server startup failed: " + startupMsg);
|
||||
}
|
||||
return new ServerWrapper(processHandler, null);
|
||||
}
|
||||
|
||||
private static RequestFuture sendSetupRequest(final @NotNull CompileServerClient client) throws Exception {
|
||||
final Map<String, String> data = new HashMap<String, String>();
|
||||
|
||||
@@ -593,7 +570,7 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
// commandLine.add((launcherUsed? "-J" : "") + "-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + CharsetToolkit.getDefaultSystemCharset().name());
|
||||
//}
|
||||
|
||||
private Process launchServer(final int port, long pingInterval, File workDirectory) throws ExecutionException {
|
||||
private Process launchServer(final int port, long pingInterval) throws ExecutionException {
|
||||
// validate tools.jar presence
|
||||
final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler();
|
||||
if (systemCompiler == null) {
|
||||
@@ -642,6 +619,9 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
if (Registry.is("compiler.server.use.memory.temp.cache")) {
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION + "=true");
|
||||
}
|
||||
if (Registry.is("compiler.server.use.external.javac.process")) {
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.USE_EXTERNAL_JAVAC_OPTION + "=true");
|
||||
}
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.HOSTNAME_OPTION + "=" + NetUtils.getLocalHostString());
|
||||
|
||||
// javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
|
||||
@@ -672,6 +652,10 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
cmdLine.addParameter(org.jetbrains.jps.server.Server.class.getName());
|
||||
cmdLine.addParameter(Integer.toString(port));
|
||||
|
||||
final File workDirectory = new File(mySystemDirectory, COMPILE_SERVER_SYSTEM_ROOT);
|
||||
workDirectory.mkdirs();
|
||||
ensureLogConfigExists(workDirectory);
|
||||
|
||||
cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath()));
|
||||
|
||||
cmdLine.setWorkDirectory(workDirectory);
|
||||
@@ -711,7 +695,7 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
shutdownServer(myClient, myProcessHandler);
|
||||
}
|
||||
|
||||
private static void shutdownServer(final CompileServerClient client, final ServerWrapper processHandler) {
|
||||
private static void shutdownServer(final CompileServerClient client, final OSProcessHandler processHandler) {
|
||||
try {
|
||||
if (client != null && client.isConnected()) {
|
||||
final Future future = client.sendShutdownRequest();
|
||||
@@ -884,28 +868,4 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ServerWrapper {
|
||||
final @Nullable OSProcessHandler myHandler;
|
||||
final @Nullable Server myServer;
|
||||
|
||||
ServerWrapper(OSProcessHandler handler, Server server) {
|
||||
myHandler = handler;
|
||||
myServer = server;
|
||||
}
|
||||
|
||||
public void destroyProcess() {
|
||||
if (myHandler != null) {
|
||||
myHandler.destroyProcess();
|
||||
} else if (myServer != null) {
|
||||
myServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDead() {
|
||||
return myHandler != null && (myHandler.isProcessTerminated() || myHandler.isProcessTerminating()) ||
|
||||
myServer != null && myServer.isStopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.io.MappingFailedException;
|
||||
import com.intellij.util.io.PersistentEnumerator;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.*;
|
||||
import org.jetbrains.jps.api.CanceledStatus;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
import org.jetbrains.jps.api.RequestFuture;
|
||||
import org.jetbrains.jps.api.SharedThreadPool;
|
||||
import org.jetbrains.jps.incremental.java.ExternalJavacDescriptor;
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder;
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilderLogger;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||
@@ -164,7 +164,7 @@ public class IncProjectBuilder {
|
||||
return context;
|
||||
}
|
||||
|
||||
private static void flushContext(@Nullable CompileContext context) {
|
||||
private static void flushContext(CompileContext context) {
|
||||
if (context != null) {
|
||||
context.getTimestampStorage().force();
|
||||
context.getDataManager().flush(false);
|
||||
@@ -181,16 +181,14 @@ public class IncProjectBuilder {
|
||||
}
|
||||
ExternalJavacDescriptor.KEY.set(context, null);
|
||||
}
|
||||
if (context == null || context.getBuilderParameter(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null) {
|
||||
cleanupJavacNameTable();
|
||||
}
|
||||
cleanupJavacNameTable();
|
||||
}
|
||||
|
||||
private static boolean ourClenupFailed = false;
|
||||
|
||||
private static void cleanupJavacNameTable() {
|
||||
try {
|
||||
if (!ourClenupFailed) {
|
||||
if (JavaBuilder.USE_EMBEDDED_JAVAC && !ourClenupFailed) {
|
||||
final Field freelistField = Class.forName("com.sun.tools.javac.util.Name$Table").getDeclaredField("freelist");
|
||||
freelistField.setAccessible(true);
|
||||
freelistField.set(null, com.sun.tools.javac.util.List.nil());
|
||||
|
||||
@@ -56,6 +56,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
private static final String FORMS_BUILDER_NAME = "forms";
|
||||
private static final String JAVA_EXTENSION = ".java";
|
||||
private static final String FORM_EXTENSION = ".form";
|
||||
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
|
||||
|
||||
public static final FileFilter JAVA_SOURCES_FILTER = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
@@ -385,7 +386,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
|
||||
try {
|
||||
final boolean rc;
|
||||
if (context.getBuilderParameter(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null) {
|
||||
if (USE_EMBEDDED_JAVAC) {
|
||||
rc = JavacMain.compile(
|
||||
options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus()
|
||||
);
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Server {
|
||||
private final ScheduledExecutorService myScheduler;
|
||||
private final ServerMessageHandler myMessageHandler;
|
||||
|
||||
public Server(File systemDir, boolean cachesInMemory) {
|
||||
public Server(File systemDir) {
|
||||
Utils.setSystemRoot(systemDir);
|
||||
final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
myScheduler = ConcurrencyUtil.newSingleScheduledThreadExecutor("Client activity checker", Thread.MIN_PRIORITY);
|
||||
@@ -105,17 +105,6 @@ public class Server {
|
||||
);
|
||||
}
|
||||
};
|
||||
ServerState.getInstance().setKeepTempCachesInMemory(cachesInMemory);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
|
||||
public void run() {
|
||||
try {
|
||||
myMessageHandler.cancelAllBuildsAndClearState();
|
||||
}
|
||||
finally {
|
||||
Server.this.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void start(int listenPort) {
|
||||
@@ -192,10 +181,6 @@ public class Server {
|
||||
myLastPingTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean isStopped() {
|
||||
return myScheduler.isShutdown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
int port = DEFAULT_SERVER_PORT;
|
||||
@@ -212,10 +197,21 @@ public class Server {
|
||||
systemDir = new File(args[1]);
|
||||
}
|
||||
|
||||
final Server server = new Server(systemDir, System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null);
|
||||
final Server server = new Server(systemDir);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
|
||||
public void run() {
|
||||
try {
|
||||
server.myMessageHandler.cancelAllBuildsAndClearState();
|
||||
}
|
||||
finally {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
initLoggers();
|
||||
server.start(port);
|
||||
ServerState.getInstance().setKeepTempCachesInMemory(System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null);
|
||||
|
||||
System.out.println("Server classpath: " + System.getProperty("java.class.path"));
|
||||
System.err.println(SERVER_SUCCESS_START_MESSAGE + port);
|
||||
|
||||
@@ -151,9 +151,6 @@ compiler.server.use.external.javac.process.description=Run javac compiler in ext
|
||||
compiler.server.ping.interval=5
|
||||
compiler.server.ping.interval.description=Interval in seconds between ping requests the IDE periodically sends to server. If server does not receive pings for some time, it shuts down. Specify -1 to disable this feature.
|
||||
|
||||
compiler.server.in.process=false
|
||||
compiler.server.in.process.description=Launch compiler server in IDEA process
|
||||
|
||||
compiler.server.debug.port=-1
|
||||
#compiler.server.javac.debug.port=-1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user