2
0
Эх сурвалжийг харах

VSCode: multi instance management fix

paviko 6 өдөр өмнө
parent
commit
cde12cd493

+ 3 - 4
hosts/vscode-plugin/src/ui/ActivityBarProvider.ts

@@ -69,11 +69,10 @@ export class ActivityBarProvider implements vscode.WebviewViewProvider {
         this.controller = undefined
       }
 
-      // Clear command routing pointer if it pointed to this controller
+      // Remove this bridge from PathInserter registry; it will fall back to another if available
       try {
-        const current = PathInserter.getCommunicationBridge()
-        if (current && bridge && current === bridge) {
-          PathInserter.clearCommunicationBridge()
+        if (bridge) {
+          PathInserter.removeCommunicationBridge(bridge)
         }
       } catch {}
       this.view = undefined

+ 9 - 7
hosts/vscode-plugin/src/ui/WebviewManager.ts

@@ -151,12 +151,12 @@ export class WebviewManager {
           this.uiState = state
         },
       })
-      // Keep references for compatibility APIs
-      this.communicationBridge = this.controller.getCommunicationBridge?.()
-
       // Load UI via controller
       await this.controller.load(connection)
 
+      // Keep references for compatibility APIs (must be after load() which creates the bridge)
+      this.communicationBridge = this.controller.getCommunicationBridge()
+
       // Prefer routing commands to this panel when visible
       if (this.panel.visible) {
         const bridge = this.controller.getCommunicationBridge()
@@ -219,6 +219,9 @@ export class WebviewManager {
    * Clean up resources
    */
   private cleanup(): void {
+    // Grab bridge ref before controller.dispose() clears it
+    const bridge = this.communicationBridge ?? this.controller?.getCommunicationBridge()
+
     if (this.controller) {
       try {
         this.controller.dispose()
@@ -226,11 +229,10 @@ export class WebviewManager {
       this.controller = undefined
     }
 
-    // Clear command routing pointer if it pointed to this controller
+    // Remove this bridge from PathInserter registry; it will fall back to another if available
     try {
-      const current = PathInserter.getCommunicationBridge()
-      if (current && current === this.communicationBridge) {
-        PathInserter.clearCommunicationBridge()
+      if (bridge) {
+        PathInserter.removeCommunicationBridge(bridge)
       }
     } catch {}
     if (this.communicationBridge) {

+ 30 - 1
hosts/vscode-plugin/src/utils/PathInserter.ts

@@ -11,6 +11,7 @@ import { logger } from "../globals"
  */
 export class PathInserter {
   private static communicationBridge: CommunicationBridge | undefined
+  private static bridges = new Set<CommunicationBridge>()
 
   static getCommunicationBridge(): CommunicationBridge | undefined {
     return this.communicationBridge
@@ -21,6 +22,9 @@ export class PathInserter {
    * @param bridge The communication bridge to use for communication
    */
   static setCommunicationBridge(bridge: CommunicationBridge | undefined): void {
+    if (bridge) {
+      this.bridges.add(bridge)
+    }
     this.communicationBridge = bridge
     if (bridge) {
       logger.appendLine("Communication bridge set for PathInserter")
@@ -29,6 +33,22 @@ export class PathInserter {
     }
   }
 
+  /**
+   * Remove a specific bridge and fall back to another registered bridge if it was active
+   */
+  static removeCommunicationBridge(bridge: CommunicationBridge): void {
+    this.bridges.delete(bridge)
+    if (this.communicationBridge === bridge) {
+      const remaining = [...this.bridges]
+      this.communicationBridge = remaining.length > 0 ? remaining[remaining.length - 1] : undefined
+      logger.appendLine(
+        this.communicationBridge
+          ? "Communication bridge fell back to another instance"
+          : "Communication bridge cleared from PathInserter",
+      )
+    }
+  }
+
   /**
    * Set the webview panel for JavaScript execution (deprecated - use setCommunicationBridge)
    * @param panel The webview panel to use for communication
@@ -179,7 +199,16 @@ export class PathInserter {
    * Clear the communication bridge reference
    */
   static clearCommunicationBridge(): void {
-    this.setCommunicationBridge(undefined)
+    if (this.communicationBridge) {
+      this.bridges.delete(this.communicationBridge)
+    }
+    const remaining = [...this.bridges]
+    this.communicationBridge = remaining.length > 0 ? remaining[remaining.length - 1] : undefined
+    logger.appendLine(
+      this.communicationBridge
+        ? "Communication bridge fell back to another instance"
+        : "Communication bridge cleared from PathInserter",
+    )
   }
 
   /**