Skip to content
55 changes: 55 additions & 0 deletions python/sglang/srt/disaggregation/mori/conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

logger = logging.getLogger(__name__)
MORI_GUARD = b"MoriMsgGuard"
_TAG_ABORT = b"ABORT"


def _normalize_state_indices_per_component(
Expand Down Expand Up @@ -552,11 +553,52 @@ def _validate_message(self, msg: List[bytes]) -> Optional[List[bytes]]:
return None
return payload

def _handle_abort_message(self, msg: List[bytes]) -> None:
"""Handle best-effort ABORT notifications from the decode side."""
if len(msg) < 2:
logger.warning("Malformed ABORT message: too few frames (%d)", len(msg))
return

try:
bootstrap_room = int(msg[1].decode("ascii"))
except (ValueError, UnicodeDecodeError):
logger.warning("Malformed ABORT message: invalid room field %r", msg[1])
return

with self.transfer_lock:
current = self.request_status.get(bootstrap_room)
if current is None:
logger.debug(
"ABORT for room %s is not tracked; ignoring",
bootstrap_room,
)
return
if current == KVPoll.Success:
logger.debug(
"ABORT for room %s already succeeded; ignoring",
bootstrap_room,
)
return
if current == KVPoll.Failed:
return

self.update_status(bootstrap_room, KVPoll.Failed)

logger.debug("Room %s marked Failed via ABORT from decode", bootstrap_room)

def _start_bootstrap_thread(self) -> None:
def bootstrap_worker():
while True:
try:
msg = self.server_socket.recv_multipart()
if not msg:
continue

tag = msg[0]
if tag == _TAG_ABORT:
self._handle_abort_message(msg)
continue

payload = self._validate_message(msg)
if payload is None:
continue
Expand Down Expand Up @@ -599,6 +641,12 @@ def decode_worker():
logger.warning("Incomplete status payload received")
continue
bootstrap_room = int(payload[0].decode("ascii"))
if bootstrap_room not in self.request_status:
logger.debug(
"Dropping late status for cleared room %s",
bootstrap_room,
)
continue
status_code = int(payload[1].decode("ascii"))
prefill_rank = int(payload[2].decode("ascii"))
failure_reason = (
Expand Down Expand Up @@ -1318,6 +1366,10 @@ def add_transfer_request(
targets: List[TransferTarget] = []
target_infos_snapshot: Optional[List[TransferInfo]] = None
with self.transfer_lock:
current = self.request_status.get(bootstrap_room)
if current is None or current == KVPoll.Failed:
return [], None

transfer_infos = self.transfer_infos.get(bootstrap_room)
if not transfer_infos:
reason = f"No transfer info found for bootstrap_room={bootstrap_room}"
Expand Down Expand Up @@ -1803,8 +1855,11 @@ def failure_exception(self):
def abort(self):
if self.bootstrap_room is None:
return
bootstrap_room = self.bootstrap_room
super().abort()
self.clear()
with self.kv_mgr.failure_lock:
self.kv_mgr.failure_records.pop(bootstrap_room, None)


class MoriKVBootstrapServer(CommonKVBootstrapServer):
Expand Down
Loading