1111from dataclasses import dataclass
1212from enum import Enum
1313from pathlib import Path
14- from typing import Callable , Optional , Union
14+ from collections . abc import Callable
1515
1616import requests
1717
@@ -32,7 +32,7 @@ class ServerStatus(Enum):
3232@dataclass
3333class PortConflict :
3434 """Returned by start() when the port is already in use."""
35- pid : Optional [ int ]
35+ pid : int | None
3636 is_omlx : bool
3737
3838
@@ -58,12 +58,12 @@ class ServerManager:
5858
5959 def __init__ (self , config : ServerConfig ):
6060 self .config = config
61- self ._process : Optional [ subprocess .Popen ] = None
61+ self ._process : subprocess .Popen | None = None
6262 self ._status = ServerStatus .STOPPED
63- self ._error_message : Optional [ str ] = None
63+ self ._error_message : str | None = None
6464 self ._log_file_handle = None
65- self ._status_callback : Optional [ Callable [[ServerStatus ], None ]] = None
66- self ._health_check_thread : Optional [ threading .Thread ] = None
65+ self ._status_callback : Callable [[ServerStatus ], None ] | None = None
66+ self ._health_check_thread : threading .Thread | None = None
6767 self ._stop_health_check = threading .Event ()
6868 self ._adopted = False
6969
@@ -82,13 +82,13 @@ def status(self) -> ServerStatus:
8282 return self ._status
8383
8484 @property
85- def error_message (self ) -> Optional [ str ] :
85+ def error_message (self ) -> str | None :
8686 return self ._error_message
8787
8888 def set_status_callback (self , callback : Callable [[ServerStatus ], None ]) -> None :
8989 self ._status_callback = callback
9090
91- def _update_status (self , status : ServerStatus , error : Optional [ str ] = None ) -> None :
91+ def _update_status (self , status : ServerStatus , error : str | None = None ) -> None :
9292 self ._status = status
9393 self ._error_message = error
9494 if self ._status_callback :
@@ -237,7 +237,7 @@ def _is_omlx_server(self) -> bool:
237237 except requests .RequestException :
238238 return False
239239
240- def _find_port_owner_pid (self ) -> Optional [ int ] :
240+ def _find_port_owner_pid (self ) -> int | None :
241241 """Find the PID of the process listening on the configured port."""
242242 try :
243243 result = subprocess .run (
@@ -290,7 +290,7 @@ def adopt(self) -> bool:
290290 logger .info (f"Adopted external oMLX server on port { self .config .port } " )
291291 return True
292292
293- def _do_start (self ) -> Union [ bool , PortConflict ] :
293+ def _do_start (self ) -> bool | PortConflict :
294294 """Core start logic shared by start() and auto-restart.
295295
296296 Does NOT check current status or start the health check thread.
@@ -331,7 +331,7 @@ def _do_start(self) -> Union[bool, PortConflict]:
331331 logger .error (f"Failed to start server: { e } " )
332332 return False
333333
334- def start (self ) -> Union [ bool , PortConflict ] :
334+ def start (self ) -> bool | PortConflict :
335335 if self ._status in (ServerStatus .RUNNING , ServerStatus .STARTING ):
336336 return False
337337
@@ -352,7 +352,7 @@ def start(self) -> Union[bool, PortConflict]:
352352
353353 return result
354354
355- def force_restart (self ) -> Union [ bool , PortConflict ] :
355+ def force_restart (self ) -> bool | PortConflict :
356356 """Force restart: kill process, reset counters, and start fresh."""
357357 self ._cleanup_dead_process ()
358358 self ._auto_restart_count = 0
@@ -422,7 +422,7 @@ def stop(self, timeout: float = 10.0) -> bool:
422422 self ._update_status (ServerStatus .ERROR , str (e ))
423423 return False
424424
425- def restart (self ) -> Union [ bool , PortConflict ] :
425+ def restart (self ) -> bool | PortConflict :
426426 self .stop ()
427427 import time
428428 time .sleep (1 )
0 commit comments