From 6d7214122c42e6d023f4233a4ef3970ba421c15f Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Fri, 18 Feb 2011 19:52:32 +0300 Subject: [PATCH] Fixed 3 problems with console: xmlrpc hangs up without timelimit, close action doesn't work, disconnect on ide close doesn't work too. --- .../console/pydev/PydevXmlRpcClient.java | 8 +++- .../console/PyConsoleProcessHandler.java | 41 ++++++++++++++++--- .../python/console/PydevConsoleRunner.java | 15 ++++++- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/python/pydevSrc/com/jetbrains/python/console/pydev/PydevXmlRpcClient.java b/python/pydevSrc/com/jetbrains/python/console/pydev/PydevXmlRpcClient.java index 6e87fcd8b3e2..b5e4ab2df6b5 100644 --- a/python/pydevSrc/com/jetbrains/python/console/pydev/PydevXmlRpcClient.java +++ b/python/pydevSrc/com/jetbrains/python/console/pydev/PydevXmlRpcClient.java @@ -44,6 +44,8 @@ public class PydevXmlRpcClient implements IPydevXmlRpcClient { */ private static final Logger LOG = Logger.getInstance(PydevXmlRpcClient.class.getName()); + private static final long TIME_LIMIT = 5000; + /** * Constructor (see fields description) @@ -79,8 +81,9 @@ public class PydevXmlRpcClient implements IPydevXmlRpcClient { } }); + long started = System.currentTimeMillis(); //busy loop waiting for the answer (or having the console die). - while (result[0] == null) { + while (result[0] == null && System.currentTimeMillis() - started < TIME_LIMIT) { try { if (process != null) { final String errStream = stdErrReader.getContents(); @@ -113,6 +116,9 @@ public class PydevXmlRpcClient implements IPydevXmlRpcClient { } } } + if (result[0] == null) { + throw new XmlRpcException(-1, "Timeout while connecting to server"); + } return result[0]; } } diff --git a/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java b/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java index 6a686a71dabe..6a6b29d23039 100644 --- a/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java +++ b/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java @@ -1,9 +1,9 @@ package com.jetbrains.python.console; import com.intellij.execution.console.LanguageConsoleImpl; -import com.intellij.execution.process.ColoredProcessHandler; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; +import com.jetbrains.python.console.pydev.PydevConsoleCommunication; import com.jetbrains.python.run.PythonProcessHandler; import java.nio.charset.Charset; @@ -13,13 +13,15 @@ import java.nio.charset.Charset; */ public class PyConsoleProcessHandler extends PythonProcessHandler { private final LanguageConsoleImpl myLanguageConsole; + private final PydevConsoleCommunication myPydevConsoleCommunication; public PyConsoleProcessHandler(final Process process, final LanguageConsoleImpl languageConsole, - final String commandLine, + PydevConsoleCommunication pydevConsoleCommunication, final String commandLine, final Charset charset) { super(process, commandLine, charset); myLanguageConsole = languageConsole; + myPydevConsoleCommunication = pydevConsoleCommunication; } @@ -42,18 +44,19 @@ public class PyConsoleProcessHandler extends PythonProcessHandler { for (String prompt : PROMPTS) { if (string.startsWith(prompt)) { // Process multi prompts here - if (prompt != PyConsoleHighlightingUtil.HELP_PROMPT){ + if (prompt != PyConsoleHighlightingUtil.HELP_PROMPT) { final StringBuilder builder = new StringBuilder(); builder.append(prompt).append(prompt); - while (string.startsWith(builder.toString())){ + while (string.startsWith(builder.toString())) { builder.append(prompt); } final String multiPrompt = builder.toString().substring(prompt.length()); - if (prompt == PyConsoleHighlightingUtil.INDENT_PROMPT){ + if (prompt == PyConsoleHighlightingUtil.INDENT_PROMPT) { prompt = multiPrompt; } string = string.substring(multiPrompt.length()); - } else { + } + else { string = string.substring(prompt.length()); } @@ -68,4 +71,30 @@ public class PyConsoleProcessHandler extends PythonProcessHandler { } return string; } + + @Override + protected void destroyProcessImpl() { + doCloseCommunication(); + super.destroyProcessImpl(); + } + + @Override + protected void detachProcessImpl() { + doCloseCommunication(); + super.detachProcessImpl(); + } + + private void doCloseCommunication() { + if (myPydevConsoleCommunication != null) { + try { + myPydevConsoleCommunication.close(); + // waiting for REPL communication before destroying process handler + Thread.sleep(300); + } + catch (Exception e1) { + // Ignore + } + } + } } + diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java index 0e2e3cd79297..96fde13ede93 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java @@ -3,12 +3,14 @@ package com.jetbrains.python.console; import com.google.common.collect.ImmutableMap; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionHelper; +import com.intellij.execution.Executor; import com.intellij.execution.console.LanguageConsoleImpl; import com.intellij.execution.console.LanguageConsoleViewImpl; import com.intellij.execution.process.CommandLineArgumentsProvider; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory; import com.intellij.execution.runners.ConsoleExecuteActionHandler; +import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.Project; @@ -121,7 +123,7 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory { @Override protected PyConsoleProcessHandler createProcessHandler(final Process process, final String commandLine) { - myProcessHandler = new PyConsoleProcessHandler(process, getConsoleView().getConsole(), commandLine, + myProcessHandler = new PyConsoleProcessHandler(process, getConsoleView().getConsole(), myPydevConsoleCommunication, commandLine, CharsetToolkit.UTF8_CHARSET); return myProcessHandler; } @@ -185,6 +187,17 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory { @Override protected AnAction createStopAction() { final AnAction generalStopAction = super.createStopAction(); + return createConsoleStoppingAction(generalStopAction); + } + + @Override + protected AnAction createCloseAction(Executor defaultExecutor, RunContentDescriptor myDescriptor) { + final AnAction generalCloseAction = super.createCloseAction(defaultExecutor, myDescriptor); + return createConsoleStoppingAction(generalCloseAction); + } + + + private AnAction createConsoleStoppingAction(final AnAction generalStopAction) { final AnAction stopAction = new AnAction() { @Override public void update(AnActionEvent e) {