@@ -133,37 +133,29 @@ def get_sessions(self) -> dict[str, SessionHealthInfo]:
133133 }
134134
135135 async def remove_session (self , session_id : str , reason : str ) -> None :
136- """Remove and stop a session by ID (SessionProvider protocol)."""
136+ """Pop, stop, and clean up a single session (SessionProvider protocol)."""
137137 session_server = self ._session_servers .pop (session_id , None )
138- if session_server is not None :
139- logger .warning (
140- f"Removing session { session_id } : { reason } "
141- )
142- try :
143- await session_server .stop ()
144- except Exception :
145- logger .error (
146- f"Error stopping session { session_id } during watchdog removal" ,
147- exc_info = True ,
148- )
149- await self ._close_session_on_server (session_id )
138+ if session_server is None :
139+ return
140+
141+ logger .warning (f"Removing session { session_id } : { reason } " )
150142
151- async def _close_session_on_server (self , session_id : str ) -> None :
152- """Notify the UiPath server to remove a session so it stops sending messages."""
153143 try :
154- await self ._uipath .api_client .request_async (
155- "DELETE" ,
156- f"agenthub_/mcp/{ self ._folder_key } /{ self .slug } " ,
157- headers = {"mcp-session-id" : session_id },
144+ await session_server .stop ()
145+ except Exception :
146+ logger .error (
147+ f"Error stopping session { session_id } " ,
148+ exc_info = True ,
158149 )
159- logger . info ( f"Notified server of session closure: { session_id } " )
160- except HTTPStatusError as e :
161- if e . response . status_code == 404 :
162- logger . info ( f"Session { session_id } already removed server-side" )
150+
151+ if session_server . output :
152+ if self . sandboxed :
153+ self . _session_output = session_server . output
163154 else :
164- logger .error (f"Error closing session { session_id } on server: { e } " )
165- except Exception as e :
166- logger .error (f"Error closing session { session_id } on server: { e } " )
155+ logger .info (f"Session { session_id } output: { session_server .output } " )
156+
157+ if self .sandboxed :
158+ self ._cancel_event .set ()
167159
168160 async def get_schema (self ) -> UiPathRuntimeSchema :
169161 """Get schema for this MCP runtime.
@@ -366,11 +358,8 @@ async def _cleanup(self) -> None:
366358 await self ._watchdog .stop ()
367359 self ._watchdog = None
368360
369- for session_id , session_server in list (self ._session_servers .items ()):
370- try :
371- await session_server .stop ()
372- except Exception as e :
373- logger .error (f"Error cleaning up session server { session_id } : { str (e )} " )
361+ for session_id in list (self ._session_servers .keys ()):
362+ await self .remove_session (session_id , reason = "runtime shutdown" )
374363
375364 # Stop the shared HTTP server process (streamable-http only)
376365 await self ._stop_http_server_process ()
@@ -396,26 +385,8 @@ async def _handle_signalr_session_closed(self, args: list[str]) -> None:
396385 return
397386
398387 session_id = args [0 ]
399-
400388 logger .info (f"Received closed signal for session { session_id } " )
401-
402- try :
403- session_server = self ._session_servers .pop (session_id , None )
404- if session_server :
405- await session_server .stop ()
406- if session_server .output :
407- if self .sandboxed :
408- self ._session_output = session_server .output
409- else :
410- logger .info (
411- f"Session { session_id } output: { session_server .output } "
412- )
413- # If this is a sandboxed runtime for a specific session, cancel the execution
414- if self .sandboxed :
415- self ._cancel_event .set ()
416-
417- except Exception as e :
418- logger .error (f"Error terminating session { session_id } : { str (e )} " )
389+ await self .remove_session (session_id , reason = "server closed" )
419390
420391 async def _handle_signalr_message (self , args : list [str ]) -> None :
421392 """
@@ -619,13 +590,9 @@ async def _monitor_http_server_process(self) -> None:
619590 # Stop all HTTP sessions, they will fail on next request anyway
620591 for session_id , session_server in list (self ._session_servers .items ()):
621592 if isinstance (session_server , StreamableHttpSessionServer ):
622- try :
623- await session_server .stop ()
624- except Exception as e :
625- logger .error (
626- f"Error stopping session { session_id } after process crash: { e } "
627- )
628- self ._session_servers .pop (session_id , None )
593+ await self .remove_session (
594+ session_id , reason = "http process crash"
595+ )
629596 except asyncio .CancelledError :
630597 pass
631598
@@ -833,7 +800,7 @@ async def on_keep_alive_response(
833800 health = s .get_health_info ()
834801 runtime_sessions [sid ] = {
835802 "task_done" : health .task_done ,
836- "active_requests" : health . active_request_count ,
803+ "active_requests" : len ( s . _active_requests ) ,
837804 }
838805 logger .info (f"Runtime active sessions: { runtime_sessions } " )
839806 # If there are no active sessions and this is a sandbox environment
@@ -849,7 +816,6 @@ async def on_keep_alive_response(
849816 )
850817 self ._cancel_event .set ()
851818
852-
853819 if self ._signalr_client :
854820 logger .info ("Sending keep-alive ping..." )
855821 await self ._signalr_client .send (
0 commit comments