iouring-batch put_many — 최종 정제 (vs batch-io 비교 + PR 결정)
한 줄 요약:
_put_many_batch_io(io_uring+N>1 → 2N 엔트리 단일batched_write)는 batch-io 와 동일한 core 아이디어. 본 브랜치는 그 core 만 분리해 (1) Phase B 롤백 보완, (2) 부분 슬롯 소진 테스트 추가, (3) 실디바이스/벤치 파일 제거로 PR 을 좁힌 버전. plugin 개선(exists_many dedup 등)은 dev 독립 후속 PR 로 분리.
1. 두 브랜치 비교 (같은 목적, 다른 형태)
| 항목 | iouring-batch (1fe16ba, 6/11) | batch-io (aad5e37, 6/8 = P0 문서) |
|---|---|---|
| core 진입 분기 | io_uring && len>1 → _put_many_batch_io | 동일 |
| Phase A 슬롯 예약 | lock 1회, index/inflight 체크 후 allocate | 동일 |
| rollback 구조 | write_succeeded 플래그 + 단일 commit 루프 | commit 루프 + except 별도 rollback 루프 (중복) |
| try 범위 | 보완 전: _write_buffers만 / 보완 후: Phase B 까지 | Phase B+C+D 전체 |
zip(strict=) | strict=True | strict=False |
| header payload_len | 항상 hdr_total | hdr_total if io_uring else len(header) (이 경로는 항상 io_uring → 죽은 분기) |
| plugin 변경 | 없음 (base PR#3274 가 이미 io_uring+N>1 → 단일 put_many funnel) | batched_submit_put_task 대수술 (+67/-28) |
| 테스트 | fake io_uring device 6종 + 실디바이스 통합/벤치 | posix core 3종 (io_uring 계약 미검증) |
결론: batch-io 의 plugin 변경은 io_uring 배칭과 직교(plugin 단 dedup·lock·refcount). 즉 batch-io = iouring-batch(core) + plugin 리팩토링. "작고 집중된 PR" 관점에서 iouring-batch 를 PR 베이스로 채택, plugin 은 분리.
2. 본 브랜치 PR 결정 사항 (2026-06-11 보완)
2.1 Phase B 롤백 보완 — narrow try 확장 + 단일 루프
문제: 1fe16ba 의 try 는 _write_buffers 만 감쌌다. Phase B(_encode_header /
_prepare_write_payload)가 예외를 던지면 Phase A 에서 채운 self._inflight 엔트리와
할당 슬롯이 롤백 없이 누수된다.
방식 비교 → 채택: batch-io 의 broad-try 는 안전하지만 rollback 루프가 commit/except
두 곳에 중복. 본 브랜치는 write_succeeded 플래그 + 단일 Phase D 루프 구조를 유지한 채
try 범위만 Phase B 까지 확장 → batch-io 의 안전성을 얻으면서 중복 없음. 두 원본보다 우수.
_inflight_io_count 증감은 실제 write 에만 묶인 inner try/finally 로 유지(Phase B 가 inc
이전에 던지면 inner 블록 미실행 → 과다 감소 없음).
2.2 부분 슬롯 소진 테스트 추가
docstring 이 약속한 "keys with no free slot fail individually, 나머지는 성공" 시맨틱이
1fe16ba 에 미검증이었다. test_raw_block_core_io_uring_put_many_partial_slot_exhaustion
추가: capacity 를 meta(1MB)+3*slot(64KB) 로 줘 슬롯 3개만 두고 5키 put_many →
결과 [T,T,T,F,F], stored_keys 는 앞 3개, batched_write 1회·2*3=6 엔트리,
indexed_key_count==3, 가용 슬롯 0, 커밋분 round-trip 로드 성공. 헬퍼
_make_core_with_fake 에 capacity_bytes override 추가.
2.3 실디바이스 통합/벤치 파일 제거
test_raw_block_put_many_integration.py 는 어떤 CI 에서도 실행되지 않음:
- 전용 raw-block job(
.github/workflows/test.yml:167-172)은 device/core/l2_adapter 3개만 명시 - 일반 job 은 rust 확장 미빌드 →
importorskip모듈째 skip
fake-device 6종이 이미 계약을 CI(전용 job 의 test_raw_block_core.py)에서 검증하므로 PR
에서 제거. 파일은 로컬 보관: private/work/raw_block/local_real_device_put_many_bench.py.
실디바이스 검증은 LMCACHE_RAWBLOCK_TEST_DEVICE 지정해 로컬 수동 실행.
3. 검증 결과 (테스트 클론 /home/ny/LMCache venv, ws 소스)
pytest tests/v1/storage_backend/test_raw_block_core.py→ 11 passed (기존 6 + 신규 partial_slot_exhaustion + 기타).all_or_nothing_rollback통과로 Phase B 구조 변경이 write-failure 롤백을 깨지 않음 회귀 확인.pre-commit run --files core.py test_raw_block_core.py→ 전 항목 Passed (ruff-format 가 test 파일 1회 재포맷 후 재실행 통과).
4. 미해결 / 후속
- PR 타깃: ✅ 해소·제출 완료 — PR #3274 가 upstream/dev 에 머지된 뒤, 세 브랜치를
git rebase --onto upstream/dev로 replay. 6/11 시점 upstream/dev HEAD 는45c02cbe까지 진전(7021790 이후 추가 머지). 세 브랜치 모두 origin(nayeonikim 포크)에 push 완료: iouring-batch3b8260a0/ plugin-dedup1cc5a74d/ validate-batched-readdc3f5d36. range-diff 내용 무변, 재검증 통과(11/31/11 passed, pre-commit 전 항목).- iouring-batch → PR #3636 OPEN (dev 대상, 2026-06-11 05:43Z) — https://github.com/LMCache/LMCache/pull/3636
- plugin-dedup / validate-batched-read 는 push 만, PR 미생성(후속 독립 PR 예정).
- plugin 개선 후속 PR — ✅ 구현 완료·push 완료, PR 미생성 (브랜치
perf/rawblock-put-many-plugin-dedup, origin1cc5a74d). 이제 base 는 upstream/dev (45c02cbe) — #3274 머지로_submit_put_many가 dev 에 들어와 dev base 가능해짐.batched_submit_put_task에exists_many배치 dedup + 단일_put_lock윈도우 + dispatch 실패 try/except 롤백(ref/_put_tasks) + 빈 keys 조기 None. TDD: fake io_uring backend 테스트 2종(empty-keys, dispatch 실패 ref 롤백) red→green, plugin 전체 31 passed. iouring-batch core 와 직교(병렬 리뷰). - validate-batched-read 후속 PR — ✅ 구현 완료·push 완료, PR 미생성 (브랜치
perf/validate-batched-read, origindc3f5d36). core_validate_loaded_entries를 io_uringbatched_read로 배치화. 상세는 [[V1-validate-batched-read]]. - 실측 미검증: batch vs sequential 실디바이스 wall-clock 은 로컬 벤치 스크립트로만.