Expose child process PIDs from Engine for health check support (#23320)

This commit is contained in:
Sundara Raman Ramachandran
2026-04-23 16:44:49 -07:00
committed by GitHub
parent 9891572c4a
commit cf88fdcc9c
3 changed files with 110 additions and 0 deletions
+14
View File
@@ -55,6 +55,7 @@ from sglang.srt.entrypoints.engine_info_bootstrap_server import (
from sglang.srt.entrypoints.engine_score_mixin import EngineScoreMixin
from sglang.srt.entrypoints.EngineBase import EngineBase
from sglang.srt.managers.data_parallel_controller import (
SCHEDULER_PIDS_ARG,
run_data_parallel_controller_process,
)
from sglang.srt.managers.detokenizer_manager import run_detokenizer_process
@@ -115,6 +116,7 @@ class SchedulerInitResult:
"""Result from launching schedulers."""
scheduler_infos: List[Dict[str, Any]]
all_child_pids: List[int] = dataclasses.field(default_factory=list)
wait_for_ready: Callable[[], None] = lambda: None
wait_for_completion: Callable[[], None] = lambda: None
engine_info_bootstrap_server: Optional[Any] = None
@@ -242,6 +244,10 @@ class Engine(EngineScoreMixin, EngineBase):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
def get_all_child_pids(self) -> List[int]:
"""Returns a list of all child process PIDs."""
return self._scheduler_init_result.all_child_pids
def _resolve_routed_dp_rank(
self,
routed_dp_rank: Optional[int],
@@ -606,11 +612,17 @@ class Engine(EngineScoreMixin, EngineBase):
proc.start()
scheduler_procs.append(proc)
all_child_pids = [proc.pid for proc in scheduler_procs]
scheduler_infos = []
def wait_for_ready():
infos = _wait_for_scheduler_ready(scheduler_pipe_readers, scheduler_procs)
scheduler_infos.extend(infos)
# For dp_size > 1, collect child scheduler PIDs from the DP controller
if server_args.dp_size > 1:
for info in infos:
if SCHEDULER_PIDS_ARG in info:
all_child_pids.extend(info[SCHEDULER_PIDS_ARG])
def wait_for_completion():
for proc in scheduler_procs:
@@ -623,6 +635,7 @@ class Engine(EngineScoreMixin, EngineBase):
return (
SchedulerInitResult(
scheduler_infos=scheduler_infos,
all_child_pids=all_child_pids,
wait_for_ready=wait_for_ready,
wait_for_completion=wait_for_completion,
),
@@ -733,6 +746,7 @@ class Engine(EngineScoreMixin, EngineBase):
),
)
detoken_proc.start()
scheduler_init_result.all_child_pids.append(detoken_proc.pid)
# Init tokenizer manager first, as the bootstrap server is initialized here
if server_args.tokenizer_worker_num == 1:
@@ -66,6 +66,8 @@ from sglang.utils import TypeBasedDispatcher, get_exception_traceback
logger = logging.getLogger(__name__)
SCHEDULER_PIDS_ARG = "scheduler_pids"
class LoadBalanceMethod(Enum):
"""Load balance method."""
@@ -617,11 +619,15 @@ def run_data_parallel_controller_process(
controller = DataParallelController(
server_args, port_args, run_scheduler_process_func
)
scheduler_pids = [
proc.pid for proc in controller.scheduler_procs if proc is not None
]
pipe_writer.send(
{
"status": "ready",
"max_total_num_tokens": controller.max_total_num_tokens,
"max_req_input_len": controller.max_req_input_len,
SCHEDULER_PIDS_ARG: scheduler_pids,
}
)
if server_args.node_rank == 0: