66from jupyter_server_documents .rooms .yroom_manager import YRoomManager
77from jupyter_server_documents .rooms .yroom import YRoom
88from jupyter_server_documents .kernel_client import DocumentAwareKernelClient
9- from nextgen_kernels_api .services .kernels .client_manager import KernelClientManager
109
1110
1211class YDocSessionManager (SessionManager ):
@@ -31,11 +30,6 @@ def yroom_manager(self) -> YRoomManager:
3130 """The Jupyter Server's YRoom Manager."""
3231 return self .serverapp .web_app .settings ["yroom_manager" ]
3332
34- @property
35- def client_manager (self ) -> KernelClientManager :
36- """The Kernel Client Manager."""
37- return self .serverapp .web_app .settings ["client_manager" ]
38-
3933 _room_ids : dict [str , str ]
4034 """
4135 Dictionary of room IDs, keyed by session ID.
@@ -83,7 +77,34 @@ async def create_session(
8377 ) -> dict [str , Any ]:
8478 """
8579 After creating a session, connects the yroom to the kernel client.
80+ Sets kernel status to "starting" before kernel launch.
8681 """
82+ # For notebooks, set up the YRoom and set initial status before starting kernel
83+ should_setup_yroom = (
84+ type == "notebook" and
85+ name is not None and
86+ path is not None
87+ )
88+
89+ yroom = None
90+ if should_setup_yroom :
91+ # Calculate the real path
92+ real_path = os .path .join (os .path .split (path )[0 ], name )
93+
94+ # Initialize the YRoom before starting the kernel
95+ file_id = self .file_id_manager .index (real_path )
96+ room_id = f"json:notebook:{ file_id } "
97+ yroom = self .yroom_manager .get_room (room_id )
98+
99+ # Set initial kernel status to "starting" in awareness
100+ awareness = yroom .get_awareness ()
101+ if awareness is not None :
102+ self .log .info ("Setting kernel execution_state to 'starting' before kernel launch" )
103+ awareness .set_local_state_field (
104+ "kernel" , {"execution_state" : "starting" }
105+ )
106+
107+ # Now create the session and start the kernel
87108 session_model = await super ().create_session (
88109 path ,
89110 name ,
@@ -108,27 +129,21 @@ async def create_session(
108129 self .log .warning (f"`name` or `path` was not given for new session at '{ path } '." )
109130 return session_model
110131
111- # Otherwise, get a `YRoom` and add it to this session's kernel client.
112-
113- # When JupyterLab creates a session, it uses a fake path
114- # which is the relative path + UUID, i.e. the notebook
115- # name is incorrect temporarily. It later makes multiple
116- # updates to the session to correct the path.
117- #
118- # Here, we create the true path to store in the fileID service
119- # by dropping the UUID and appending the file name.
120- real_path = os .path .join (os .path .split (path )[0 ], name )
132+ # Otherwise, add the YRoom to this session's kernel client.
121133
122- # Get YRoom for this session and store its ID in `self._room_ids`
123- yroom = self ._init_session_yroom (session_id , real_path )
134+ # Store the room ID for this session
135+ if yroom :
136+ self ._room_ids [session_id ] = yroom .room_id
137+ else :
138+ # Shouldn't happen, but handle it anyway
139+ real_path = os .path .join (os .path .split (path )[0 ], name )
140+ yroom = self ._init_session_yroom (session_id , real_path )
124141
125142 # Add YRoom to this session's kernel client
126- # TODO: we likely have a race condition here... need to
127- # think about it more. Currently, the kernel client gets
128- # created after the kernel starts fully. We need the
129- # kernel client instantiated _before_ trying to connect
130- # the yroom.
131- kernel_client = self .client_manager .get_client (kernel_id )
143+ # Ensure the kernel client is fully connected before proceeding
144+ # to avoid queuing messages on first execution
145+ kernel_manager = self .serverapp .kernel_manager .get_kernel (kernel_id )
146+ kernel_client = kernel_manager .kernel_client
132147 await kernel_client .add_yroom (yroom )
133148 self .log .info (f"Connected yroom { yroom .room_id } to kernel { kernel_id } . yroom: { yroom } " )
134149 return session_model
@@ -158,10 +173,12 @@ async def update_session(self, session_id: str, **update) -> None:
158173 )
159174 yroom = self .get_yroom (session_id )
160175 if old_kernel_id :
161- old_kernel_client = self .client_manager .get_client (old_kernel_id )
176+ old_kernel_manager = self .serverapp .kernel_manager .get_kernel (old_kernel_id )
177+ old_kernel_client = old_kernel_manager .kernel_client
162178 await old_kernel_client .remove_yroom (yroom = yroom )
163179 if new_kernel_id :
164- new_kernel_client = self .client_manager .get_client (new_kernel_id )
180+ new_kernel_manager = self .serverapp .kernel_manager .get_kernel (new_kernel_id )
181+ new_kernel_client = new_kernel_manager .kernel_client
165182 await new_kernel_client .add_yroom (yroom = yroom )
166183
167184 # Apply update and return
@@ -177,7 +194,8 @@ async def delete_session(self, session_id):
177194
178195 # Remove YRoom from session's kernel client
179196 yroom = self .get_yroom (session_id )
180- kernel_client = self .client_manager .get_client (kernel_id )
197+ kernel_manager = self .serverapp .kernel_manager .get_kernel (kernel_id )
198+ kernel_client = kernel_manager .kernel_client
181199 await kernel_client .remove_yroom (yroom )
182200
183201 # Remove room ID stored for the session
0 commit comments