@@ -11,7 +11,7 @@ import {
1111 INotebookTracker ,
1212 NotebookPanel
1313} from '@jupyterlab/notebook' ;
14- import { KernelMessage } from '@jupyterlab/services' ;
14+ import { KernelMessage , Kernel } from '@jupyterlab/services' ;
1515import { JSONObject , JSONValue , Token } from '@lumino/coreutils' ;
1616import { DisposableDelegate } from '@lumino/disposable' ;
1717import { NotebookInfo } from '../utils/notebook' ;
@@ -49,6 +49,43 @@ implements
4949 DocumentRegistry . IWidgetExtension < NotebookPanel , INotebookModel > ,
5050 ICommunicationService {
5151 private _comms = new Map < string , ICommunicationChannel > ( ) ;
52+
53+ /*
54+ * Attempts to open a comm channel with a retry mechanism.
55+ * @param kernel The kernel for which a comm channel is being created.
56+
57+ * @returns A promise that resolves when the comm is open.
58+ */
59+ private async _createAndOpenCommWithRetry ( kernel : Kernel . IKernelConnection , channelName : string ) : Promise < Kernel . IComm | null > {
60+ let attempt = 1 ;
61+ let delayInMS = 200 ;
62+ const maxRetries = 5 ;
63+
64+ while ( attempt <= maxRetries ) {
65+ try {
66+ // Creates comm object on the client side
67+ const comm = kernel . createComm ( channelName ) ;
68+
69+ // Attempts to open a channel with the kernel
70+ await comm . open ( ) . done ;
71+ console . log ( 'Communication channel opened successfully with ID:' , comm . commId ) ;
72+ return comm ;
73+ } catch ( error ) {
74+ console . error ( 'Error opening communication channel' , error ) ;
75+ console . error ( `Attempt #${ attempt } failed. Waiting ${ delayInMS } ms before next attempt.` ) ;
76+ }
77+ // Wait for the delay
78+ await new Promise ( resolve => setTimeout ( resolve , delayInMS ) ) ;
79+
80+ // Update
81+ delayInMS *= 2 ;
82+ attempt += 1 ;
83+ }
84+
85+ console . error ( `Failed to create communication channel after ${ attempt } attempts.` ) ;
86+ return null ;
87+ }
88+
5289 createNew (
5390 panel : NotebookPanel ,
5491 context : DocumentRegistry . IContext < INotebookModel >
@@ -75,18 +112,14 @@ implements
75112 // Create a unique channel name for this notebook
76113 const channelName = 'matlab_comm_' + panel . id ;
77114 console . log (
78- 'Attempting to create communication with the kernel using channel name' ,
79- channelName
115+ 'Attempting to establish communication with the kernel'
80116 ) ;
81- const comm = kernel . createComm ( channelName ) ;
82117
83- try {
84- await comm . open ( ) . done ;
85- console . debug ( 'Communication channel opened successfully' ) ;
86- } catch ( error ) {
87- console . error ( 'Error opening communication channel' , error ) ;
118+ const comm = await this . _createAndOpenCommWithRetry ( kernel , channelName ) ;
119+ if ( ! comm ) {
88120 return new DisposableDelegate ( ( ) => { } ) ;
89121 }
122+
90123 // Listen for messages from the kernel
91124 comm . onMsg = ( msg : KernelMessage . ICommMsgMsg ) => {
92125 const data = msg . content . data as CommunicationData ;
@@ -99,12 +132,6 @@ implements
99132 } ;
100133
101134 this . _comms . set ( panel . id , comm ) ;
102- console . log (
103- 'Communication channel created with ID: ' ,
104- comm . commId ,
105- ' and target name ' ,
106- comm . targetName
107- ) ;
108135
109136 // Clean up when notebook is disposed
110137 panel . disposed . connect ( ( ) => {
0 commit comments