diff --git a/python/pluginCore/resources/META-INF/plugin.xml b/python/pluginCore/resources/META-INF/plugin.xml
index b2e7a0856d7d..9d046539347c 100644
--- a/python/pluginCore/resources/META-INF/plugin.xml
+++ b/python/pluginCore/resources/META-INF/plugin.xml
@@ -460,6 +460,11 @@ The Python plug-in provides smart editing for Python scripts. The feature set of
+
+
+
diff --git a/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
index 77df7609bd23..716b527e424b 100644
--- a/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
+++ b/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
@@ -13,6 +13,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -33,6 +34,7 @@ import com.jetbrains.python.tables.TableCommandType;
import java.net.ServerSocket;
import java.security.SecureRandom;
+import java.time.Duration;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
@@ -88,8 +90,11 @@ public class RemoteDebugger implements ProcessDebugger {
private final long myHandshakeTimeout;
public RemoteDebugger(@NotNull IPyDebugProcess debugProcess, @NotNull String host, int port) {
+ int connectRetryTimeout = Registry.intValue("python.debugger.remote.connect.retry.timeout.ms", 500);
+ int connectMaxAttempts = Registry.intValue("python.debugger.remote.connect.max.attempts", 20);
+
myDebugProcess = debugProcess;
- myDebuggerTransport = new ClientModeDebuggerTransport(this, host, port);
+ myDebuggerTransport = new ClientModeDebuggerTransport(this, host, port, Duration.ofMillis(connectRetryTimeout), connectMaxAttempts);
myHandshakeTimeout = CLIENT_MODE_HANDSHAKE_TIMEOUT_IN_MILLIS;
}
diff --git a/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/transport/ClientModeDebuggerTransport.java b/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/transport/ClientModeDebuggerTransport.java
index eb2440ffef17..546d3e964094 100644
--- a/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/transport/ClientModeDebuggerTransport.java
+++ b/python/pydevSrc/src/com/jetbrains/python/debugger/pydev/transport/ClientModeDebuggerTransport.java
@@ -15,7 +15,7 @@ import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -56,6 +56,8 @@ public class ClientModeDebuggerTransport extends BaseDebuggerTransport {
@NotNull private final String myHost;
private final int myPort;
+ private final Duration myRetryTimeout;
+ private final int myMaxRetries;
@NotNull private volatile State myState = State.INIT;
@@ -64,10 +66,14 @@ public class ClientModeDebuggerTransport extends BaseDebuggerTransport {
public ClientModeDebuggerTransport(@NotNull RemoteDebugger debugger,
@NotNull String host,
- int port) {
+ int port,
+ Duration retryTimeout,
+ int maxRetries) {
super(debugger);
myHost = host;
myPort = port;
+ myRetryTimeout = retryTimeout;
+ myMaxRetries = maxRetries;
}
@Override
@@ -83,10 +89,7 @@ public class ClientModeDebuggerTransport extends BaseDebuggerTransport {
However, capturing stdout from the process at this point is not straightforward. Hence, we use this retry workaround.
*/
var attempts = 0;
- var maxRetries = 10;
- var retryInterval = TimeUnit.MILLISECONDS.toMillis(500);
boolean connected = false;
-
do {
try {
Socket clientSocket = new Socket();
@@ -127,14 +130,14 @@ public class ClientModeDebuggerTransport extends BaseDebuggerTransport {
catch (IOException e) {
attempts++;
try {
- Thread.sleep(retryInterval);
+ Thread.sleep(myRetryTimeout.toMillis());
}
catch (InterruptedException ex) {
- LOG.debug("Connection to the debugger thread is interrupted during the retry delay", e);
+ LOG.warn("Connection to the debugger thread is interrupted during the retry delay", e);
Thread.currentThread().interrupt();
}
}
- } while (attempts < maxRetries && !connected);
+ } while (attempts < myMaxRetries && !connected);
if (!connected) {
myState = State.DISCONNECTED;