[Bugfix] Skip absent radix lock during cache cleanup (#37494)

This commit is contained in:
YAMY
2026-09-01 22:50:19 -07:00
committed by GitHub
parent c66a285c94
commit a6a19f9290
2 changed files with 48 additions and 1 deletions
@@ -903,7 +903,9 @@ class UnifiedRadixCache(BasePrefixCache):
else:
self.free_kv_row(req.kv, [(req.kv.cache_protected_len, kv_len_to_handle)])
self._dec_req_lock(req, skip_swa=req.swa_prefix_lock_released)
# Synthetic profiling requests may own KV without locking a tree node.
if req.last_node is not None:
self._dec_req_lock(req, skip_swa=req.swa_prefix_lock_released)
if is_insert and result is not None and result.last_device_node is not None:
req.last_node = result.last_device_node
@@ -0,0 +1,45 @@
"""CPU-only tests for UnifiedRadixCache request lock lifecycle."""
import unittest
from array import array
from types import SimpleNamespace
from unittest.mock import MagicMock
import torch
from sglang.srt.mem_cache.unified_radix_cache import UnifiedRadixCache
from sglang.test.ci.ci_register import register_cpu_ci
register_cpu_ci(est_time=2, suite="base-a-test-cpu")
class TestUnifiedRadixLockRefScenarios(unittest.TestCase):
def test_no_insert_without_last_node_skips_lock_release(self):
cache = object.__new__(UnifiedRadixCache)
cache.session = MagicMock()
cache.session.try_cache_finished_req.return_value = False
cache.disable = False
cache.req_to_token_pool = MagicMock()
cache.req_to_token_pool.req_to_token = torch.arange(8).reshape(1, 8)
cache.free_kv_row = MagicMock()
cache._dec_req_lock = MagicMock()
cache._components_tuple = ()
cache.enable_session_radix_cache = False
kv = SimpleNamespace(req_pool_idx=0, cache_protected_len=0)
req = SimpleNamespace(
origin_input_ids=array("q", [1, 2, 3]),
output_ids=array("q"),
kv=kv,
last_node=None,
swa_prefix_lock_released=False,
)
cache.cache_finished_req(req, is_insert=False, kv_len_to_handle=3)
cache.free_kv_row.assert_called_once_with(kv, [(0, 3)])
cache._dec_req_lock.assert_not_called()
if __name__ == "__main__":
unittest.main()