mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-179600 - Project is disposed on reopening after docker connection
- DeploymentLogManager is project-speciifc since it is linked to console - - ServerConnection # getLogManager now requires explicit project + on project close ServerConnection should dispose per-project pieces: - - all DeploymentLogManager's for given project - - and all LocalDeploymentImpl linked via DeploymentTask # getProject
This commit is contained in:
+2
-1
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.remoteServer.runtime;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.remoteServer.configuration.RemoteServer;
|
||||
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
|
||||
import com.intellij.remoteServer.runtime.deployment.DeploymentLogManager;
|
||||
@@ -55,7 +56,7 @@ public interface ServerConnection<D extends DeploymentConfiguration> {
|
||||
Collection<Deployment> getDeployments();
|
||||
|
||||
@Nullable
|
||||
DeploymentLogManager getLogManager(@NotNull Deployment deployment);
|
||||
DeploymentLogManager getLogManager(@NotNull Project project, @NotNull Deployment deployment);
|
||||
|
||||
void connectIfNeeded(ServerConnector.ConnectionCallback<D> callback);
|
||||
}
|
||||
|
||||
+103
-21
@@ -19,6 +19,8 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerListener;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.remoteServer.configuration.RemoteServer;
|
||||
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
|
||||
@@ -37,10 +39,12 @@ import com.intellij.remoteServer.runtime.deployment.debug.DebugConnectionDataNot
|
||||
import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -51,10 +55,12 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
private final ServerConnector<D> myConnector;
|
||||
private final ServerConnectionEventDispatcher myEventDispatcher;
|
||||
private final ServerConnectionManagerImpl myConnectionManager;
|
||||
private MessageBusConnection myMessageBusConnection;
|
||||
|
||||
private volatile ConnectionStatus myStatus = ConnectionStatus.DISCONNECTED;
|
||||
private volatile String myStatusText;
|
||||
private volatile ServerRuntimeInstance<D> myRuntimeInstance;
|
||||
private final Map<String, DeploymentLogManagerImpl> myLogManagers = ContainerUtil.newConcurrentMap();
|
||||
private final Map<Project, LogManagersForProject> myPerProjectLogManagers = ContainerUtil.newConcurrentMap();
|
||||
private final MyDeployments myAllDeployments;
|
||||
|
||||
public ServerConnectionImpl(RemoteServer<?> server,
|
||||
@@ -117,8 +123,12 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
myRuntimeInstance = null;
|
||||
}
|
||||
setStatus(ConnectionStatus.DISCONNECTED);
|
||||
for (DeploymentLogManagerImpl logManager : myLogManagers.values()) {
|
||||
logManager.disposeLogs();
|
||||
for (LogManagersForProject forNextProject : myPerProjectLogManagers.values()) {
|
||||
forNextProject.disposeAllLogs();
|
||||
}
|
||||
if (myMessageBusConnection != null) {
|
||||
myMessageBusConnection.disconnect();
|
||||
myMessageBusConnection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,10 +147,11 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
String deploymentName = deployment.getName();
|
||||
myAllDeployments.addLocal(deployment);
|
||||
|
||||
DeploymentLogManagerImpl logManager = new DeploymentLogManagerImpl(task.getProject(), new ChangeListener())
|
||||
DeploymentLogManagerImpl logManager = myPerProjectLogManagers.computeIfAbsent(task.getProject(), LogManagersForProject::new)
|
||||
.findOrCreateManager(deployment)
|
||||
.withMainHandlerVisible(true);
|
||||
|
||||
LoggingHandlerImpl handler = logManager.getMainLoggingHandler();
|
||||
myLogManagers.put(deploymentName, logManager);
|
||||
handler.printlnSystemMessage("Deploying '" + deploymentName + "'...");
|
||||
onDeploymentStarted.accept(deploymentName);
|
||||
instance
|
||||
@@ -151,18 +162,15 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DeploymentLogManager getLogManager(@NotNull Deployment deployment) {
|
||||
return myLogManagers.get(deployment.getName());
|
||||
public DeploymentLogManager getLogManager(@NotNull Project project, @NotNull Deployment deployment) {
|
||||
LogManagersForProject forProject = myPerProjectLogManagers.get(project);
|
||||
return forProject == null ? null : forProject.findManager(deployment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DeploymentLogManager getOrCreateLogManager(@NotNull Project project, @NotNull Deployment deployment) {
|
||||
DeploymentLogManagerImpl result = (DeploymentLogManagerImpl)getLogManager(deployment);
|
||||
if (result == null) {
|
||||
result = new DeploymentLogManagerImpl(project, new ChangeListener());
|
||||
myLogManagers.put(deployment.getName(), result);
|
||||
}
|
||||
return result;
|
||||
LogManagersForProject forProject = myPerProjectLogManagers.computeIfAbsent(project, LogManagersForProject::new);
|
||||
return forProject.findOrCreateManager(deployment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,14 +247,18 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
|
||||
myEventDispatcher.queueDeploymentsChanged(this);
|
||||
|
||||
DeploymentLogManagerImpl logManager = myLogManagers.get(deploymentName);
|
||||
final LoggingHandlerImpl loggingHandler = logManager == null ? null : logManager.getMainLoggingHandler();
|
||||
final List<LoggingHandlerImpl> handlers = myPerProjectLogManagers.values().stream()
|
||||
.map(fnp -> fnp.findManager(deployment))
|
||||
.filter(Objects::nonNull)
|
||||
.map(DeploymentLogManagerImpl::getMainLoggingHandler)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final Consumer<String> logConsumer = message -> {
|
||||
if (loggingHandler == null) {
|
||||
if (handlers.isEmpty()) {
|
||||
LOG.info(message);
|
||||
}
|
||||
else {
|
||||
loggingHandler.printlnSystemMessage(message);
|
||||
handlers.forEach(h -> h.printlnSystemMessage(message));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -260,10 +272,7 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
undeployInProgress.succeeded();
|
||||
}
|
||||
|
||||
DeploymentLogManagerImpl logManager = myLogManagers.remove(deploymentName);
|
||||
if (logManager != null) {
|
||||
logManager.disposeLogs();
|
||||
}
|
||||
myPerProjectLogManagers.values().forEach(nextForProject -> nextForProject.disposeManager(deploymentName));
|
||||
|
||||
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
|
||||
computeDeployments(myRuntimeInstance, EmptyRunnable.INSTANCE);
|
||||
@@ -288,6 +297,18 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
return myAllDeployments.listDeployments();
|
||||
}
|
||||
|
||||
private void setupProjectListener() {
|
||||
if (myMessageBusConnection == null) {
|
||||
myMessageBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
|
||||
myMessageBusConnection.subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectClosed(Project project) {
|
||||
onProjectClosed(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectIfNeeded(final ServerConnector.ConnectionCallback<D> callback) {
|
||||
final ServerRuntimeInstance<D> instance = myRuntimeInstance;
|
||||
@@ -302,6 +323,7 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
public void connected(@NotNull ServerRuntimeInstance<D> instance) {
|
||||
setStatus(ConnectionStatus.CONNECTED);
|
||||
myRuntimeInstance = instance;
|
||||
setupProjectListener();
|
||||
callback.connected(instance);
|
||||
}
|
||||
|
||||
@@ -334,6 +356,49 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
}
|
||||
}
|
||||
|
||||
private void onProjectClosed(@NotNull Project project) {
|
||||
myPerProjectLogManagers.remove(project);
|
||||
boolean hasChanged = myAllDeployments.removedAllLocalForProject(project);
|
||||
if (hasChanged) {
|
||||
myEventDispatcher.queueDeploymentsChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
private class LogManagersForProject {
|
||||
private final Project myProject;
|
||||
private final Map<String, DeploymentLogManagerImpl> myLogManagers = ContainerUtil.newConcurrentMap();
|
||||
|
||||
public LogManagersForProject(@NotNull Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DeploymentLogManagerImpl findManager(@NotNull Deployment deployment) {
|
||||
return myLogManagers.get(deployment.getName());
|
||||
}
|
||||
|
||||
public DeploymentLogManagerImpl findOrCreateManager(@NotNull Deployment deployment) {
|
||||
return myLogManagers.computeIfAbsent(deployment.getName(), this::newDeploymentLogManager);
|
||||
}
|
||||
|
||||
private DeploymentLogManagerImpl newDeploymentLogManager(String deploymentName) {
|
||||
return new DeploymentLogManagerImpl(myProject, new ChangeListener());
|
||||
}
|
||||
|
||||
public void disposeManager(@NotNull String deploymentName) {
|
||||
DeploymentLogManagerImpl manager = myLogManagers.remove(deploymentName);
|
||||
if (manager != null) {
|
||||
manager.disposeLogs();
|
||||
}
|
||||
}
|
||||
|
||||
public void disposeAllLogs() {
|
||||
for (DeploymentLogManagerImpl nextManager : myLogManagers.values()) {
|
||||
nextManager.disposeLogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class ConnectionCallbackBase<D extends DeploymentConfiguration> implements ServerConnector.ConnectionCallback<D> {
|
||||
@Override
|
||||
public void errorOccurred(@NotNull String errorMessage) {
|
||||
@@ -504,6 +569,23 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean removedAllLocalForProject(@NotNull Project project) {
|
||||
synchronized (myLocalLock) {
|
||||
boolean hasChanged = false;
|
||||
for (Iterator<LocalDeploymentImpl> it = myLocalDeployments.values().iterator(); it.hasNext(); ) {
|
||||
LocalDeploymentImpl nextLocal = it.next();
|
||||
if (nextLocal.getDeploymentTask() != null && nextLocal.getDeploymentTask().getProject() == project) {
|
||||
it.remove();
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
if (hasChanged) {
|
||||
myCachedAllDeployments = null;
|
||||
}
|
||||
return hasChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Nullable
|
||||
public UndeployTransition startUndeploy(@NotNull String deploymentName) {
|
||||
|
||||
+4
-3
@@ -150,7 +150,8 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
|
||||
public Collection<? extends AbstractTreeNode> getChildren() {
|
||||
List<AbstractTreeNode<?>> result = new ArrayList<>();
|
||||
result.addAll(myContribution.createServerNodes(doGetProject()));
|
||||
result.addAll(ContainerUtil.map(myContribution.getRemoteServers(), (Function<RemoteServer<?>, AbstractTreeNode<?>>)server -> new RemoteServerNode(server)));
|
||||
result.addAll(ContainerUtil.map(myContribution.getRemoteServers(),
|
||||
(Function<RemoteServer<?>, AbstractTreeNode<?>>)server -> new RemoteServerNode(server)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -405,7 +406,7 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
|
||||
|
||||
@Nullable
|
||||
protected DeploymentLogManagerImpl getLogManager() {
|
||||
return (DeploymentLogManagerImpl)myConnection.getLogManager(getDeployment());
|
||||
return (DeploymentLogManagerImpl)myConnection.getLogManager(myProject, getDeployment());
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -445,7 +446,7 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
DeploymentLogManagerImpl logManager = (DeploymentLogManagerImpl)connection.getLogManager(getDeployment());
|
||||
DeploymentLogManagerImpl logManager = (DeploymentLogManagerImpl)connection.getLogManager(myProject, getDeployment());
|
||||
if (logManager != null) {
|
||||
for (LoggingHandlerBase loggingComponent : logManager.getAdditionalLoggingHandlers()) {
|
||||
children.add(new DeploymentLogNode(loggingComponent, this));
|
||||
|
||||
+5
-6
@@ -18,7 +18,6 @@ package com.intellij.remoteServer.util;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.remoteServer.ServerType;
|
||||
import com.intellij.remoteServer.agent.util.CloudAgentLoggingHandler;
|
||||
import com.intellij.remoteServer.runtime.Deployment;
|
||||
@@ -84,11 +83,11 @@ public abstract class CloudApplicationRuntime extends DeploymentRuntime {
|
||||
? null
|
||||
: new CloudLoggingHandlerImpl(deployment.getOrCreateLogManager(project)) {
|
||||
|
||||
@Override
|
||||
public void println(String message) {
|
||||
LOG.info(message);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void println(String message) {
|
||||
LOG.info(message);
|
||||
}
|
||||
};
|
||||
this.run(loggingHandler);
|
||||
return null;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user