@@ -244,8 +244,9 @@ def _cancel_restart(self, worker_id: str):
244244 if task and not task .done ():
245245 task .cancel ()
246246
247+ _SAFE_PROCESS_NAMES = {"python" , "python3" , "pythonw" , "camoufox" , "firefox" , "uv" }
248+
247249 def _free_port (self , port : int ) -> None :
248- """Kill any process occupying the given TCP port."""
249250 try :
250251 if platform .system () == "Windows" :
251252 result = subprocess .run (
@@ -257,20 +258,36 @@ def _free_port(self, port: int) -> None:
257258 parts = line .split ()
258259 pid = parts [- 1 ]
259260 if pid .isdigit ():
260- subprocess .run (
261- ["taskkill " , "/PID " , pid , "/F " ],
262- capture_output = True
261+ proc_check = subprocess .run (
262+ ["tasklist " , "/FI " , f"PID eq { pid } " , "/FO" , "CSV" , "/NH " ],
263+ capture_output = True , text = True
263264 )
264- logger .info (f"Freed port { port } (killed PID { pid } )" )
265+ proc_name = proc_check .stdout .strip ().split ("," )[0 ].strip ('"' ).lower ().replace (".exe" , "" )
266+ if proc_name in self ._SAFE_PROCESS_NAMES :
267+ subprocess .run (
268+ ["taskkill" , "/PID" , pid , "/F" ],
269+ capture_output = True
270+ )
271+ logger .info (f"Freed port { port } (killed { proc_name } PID { pid } )" )
272+ else :
273+ logger .warning (f"Port { port } occupied by { proc_name } (PID { pid } ), skipping" )
265274 else :
266275 result = subprocess .run (
267276 ["lsof" , "-ti" , f"tcp:{ port } " ],
268277 capture_output = True , text = True
269278 )
270279 for pid in result .stdout .strip ().splitlines ():
271280 if pid .isdigit ():
272- subprocess .run (["kill" , "-9" , pid ], capture_output = True )
273- logger .info (f"Freed port { port } (killed PID { pid } )" )
281+ proc_check = subprocess .run (
282+ ["ps" , "-p" , pid , "-o" , "comm=" ],
283+ capture_output = True , text = True
284+ )
285+ proc_name = proc_check .stdout .strip ().lower ()
286+ if any (safe in proc_name for safe in self ._SAFE_PROCESS_NAMES ):
287+ subprocess .run (["kill" , "-9" , pid ], capture_output = True )
288+ logger .info (f"Freed port { port } (killed { proc_name } PID { pid } )" )
289+ else :
290+ logger .warning (f"Port { port } occupied by { proc_name } (PID { pid } ), skipping" )
274291 except Exception as e :
275292 logger .warning (f"Failed to free port { port } : { e } " )
276293
0 commit comments