From b871a509e6ce047c74f575d46ac1b126a4031fd5 Mon Sep 17 00:00:00 2001 From: Liangsheng Yin Date: Wed, 15 Jul 2026 21:55:46 -0700 Subject: [PATCH] [Fix] Wire the detokenizer soft watchdog into the multi-http-worker event loop (#31392) --- .../srt/managers/multi_tokenizer_mixin.py | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/python/sglang/srt/managers/multi_tokenizer_mixin.py b/python/sglang/srt/managers/multi_tokenizer_mixin.py index ceed07b76..8a1ba1839 100644 --- a/python/sglang/srt/managers/multi_tokenizer_mixin.py +++ b/python/sglang/srt/managers/multi_tokenizer_mixin.py @@ -381,29 +381,31 @@ class MultiHttpWorkerDetokenizerMixin: def multi_http_worker_event_loop(self: DetokenizerManager): """The event loop that handles requests, for multi multi-http-worker mode""" self.socket_mapping = SocketMapping() + # Watchdog wiring mirrors DetokenizerManager.event_loop: the watchdog is + # paused while waiting for input and fed once per processed message. while True: - recv_obj = sock_recv(self.recv_from_scheduler) + with self.soft_watchdog.disable(): + recv_obj = sock_recv(self.recv_from_scheduler) output = self._request_dispatcher(recv_obj) - if output is None: - continue - - # Fan out the output back to the originating tokenizer worker(s). - # In multi-detokenizer mode the upstream MultiDetokenizerRouter may - # forward either batched or single requests, so handle both shapes. - if isinstance(recv_obj, BaseBatchReq): - for i, ipc_name in enumerate(recv_obj.http_worker_ipcs): - new_output = _handle_output_by_index(output, i) + if output is not None: + # Fan out the output back to the originating tokenizer worker(s). + # In multi-detokenizer mode the upstream MultiDetokenizerRouter may + # forward either batched or single requests, so handle both shapes. + if isinstance(recv_obj, BaseBatchReq): + for i, ipc_name in enumerate(recv_obj.http_worker_ipcs): + new_output = _handle_output_by_index(output, i) + self.socket_mapping.send_output( + ipc_name, new_output, is_tokenizer=True + ) + elif isinstance(recv_obj, BaseReq): self.socket_mapping.send_output( - ipc_name, new_output, is_tokenizer=True + recv_obj.http_worker_ipc, output, is_tokenizer=True ) - elif isinstance(recv_obj, BaseReq): - self.socket_mapping.send_output( - recv_obj.http_worker_ipc, output, is_tokenizer=True - ) - else: - raise ValueError( - f"multi_http_worker_event_loop got unexpected req type {type(recv_obj)}" - ) + else: + raise ValueError( + f"multi_http_worker_event_loop got unexpected req type {type(recv_obj)}" + ) + self.soft_watchdog.feed() class MultiTokenizerRouter: