|
| 1 | +"""Deterministic repro of lookup-hangs Defect 3: unbounded HIT_PENDING wait. |
| 2 | +
|
| 3 | +Drives the REAL TieringOffloadingManager.lookup() against a primary tier whose |
| 4 | +block is permanently write-in-flight (returns HIT_PENDING). On stock main the |
| 5 | +method returns HIT_PENDING on every call forever -> the scheduler re-polls in a |
| 6 | +hot loop and the request defers until the HTTP client times out. With the |
| 7 | +defect3 pending-wait deadline, it downgrades to MISS past 8s -> recompute. |
| 8 | +
|
| 9 | +No GPU, no HTTP, no second pod. Bypasses __init__ and sets only the three |
| 10 | +attributes the HIT_PENDING path of lookup() touches. |
| 11 | +""" |
| 12 | +import time |
| 13 | + |
| 14 | +from vllm.v1.kv_offload.base import LookupResult, ReqContext |
| 15 | +from vllm.v1.kv_offload.tiering.manager import TieringOffloadingManager |
| 16 | + |
| 17 | + |
| 18 | +class StuckPrimary: |
| 19 | + """Primary tier whose block never finishes its write (HIT_PENDING forever).""" |
| 20 | + |
| 21 | + def lookup(self, key, req_context): |
| 22 | + return LookupResult.HIT_PENDING |
| 23 | + |
| 24 | + |
| 25 | +def make_mgr(): |
| 26 | + m = object.__new__(TieringOffloadingManager) # skip the real constructor |
| 27 | + m._req_state = {} |
| 28 | + m.primary_tier = StuckPrimary() |
| 29 | + m.secondary_tiers = [] |
| 30 | + m._maybe_process_finished_jobs = lambda: None # shadow the method |
| 31 | + return m |
| 32 | + |
| 33 | + |
| 34 | +def main(): |
| 35 | + m = make_mgr() |
| 36 | + ctx = ReqContext(req_id="req-defect3") |
| 37 | + key = b"\xde\xad\xbe\xef" * 8 |
| 38 | + |
| 39 | + results = {m.lookup(key, ctx).name for _ in range(1000)} |
| 40 | + print(f"1000 rapid calls -> {results}") |
| 41 | + |
| 42 | + print("waiting 8.5s (past the 8s deadline the fix enforces)...") |
| 43 | + time.sleep(8.5) |
| 44 | + after = m.lookup(key, ctx).name |
| 45 | + print(f"after 8.5s -> {after}") |
| 46 | + |
| 47 | + if after == "HIT_PENDING": |
| 48 | + print("RESULT: DEFECT 3 REPRODUCED - block stuck HIT_PENDING with no " |
| 49 | + "downgrade; the request would hang until the client timeout.") |
| 50 | + elif after == "MISS": |
| 51 | + print("RESULT: FIXED - downgraded to MISS past the deadline; the " |
| 52 | + "request recomputes instead of hanging.") |
| 53 | + else: |
| 54 | + print(f"RESULT: unexpected terminal state {after}") |
| 55 | + |
| 56 | + |
| 57 | +if __name__ == "__main__": |
| 58 | + main() |
0 commit comments