본문으로 건너뛰기

Review: 356270ae — Harden raw-block checkpoint entry recovery


1. Summary

RawBlockCore._apply_loaded_state()는 디스크에 저장된 metadata 체크포인트를 복구해 self._index를 다시 채운다. 이전 구현에서는 한 entry 디코딩 도중 예외가 나면 (예: int("not-an-int"), torch.Size(list(non-iterable)) 등) 복구 루프 전체가 터져서 valid entry 까지 모두 손실되는 문제가 있었다.

본 커밋은:

  1. entry 디코딩 로직을 별도 헬퍼 _decode_checkpoint_entry()로 분리하고
  2. _apply_loaded_state()의 entries 루프에서 try/except로 감싸, malformed entry 한 건이 있어도 경고만 남기고 다음 entry 로 진행하도록 변경했다. 즉, "fail open" → "skip-and-continue" 정책으로 전환.
  3. partial-recovery 동작을 검증하는 회귀 테스트를 추가했다.

2. 주요 변경 사항

2.1 새 헬퍼: _decode_checkpoint_entry()

core.py:1231-1281

  • 단일 entry dict를 받아 _Entry(또는 invalid slot 인 경우 None)을 반환.
  • 기존 로직을 그대로 옮긴 형태이며, 시그니처는 (encoded_key: str, entry: dict[str, Any]) -> _Entry | None.
  • docstring 에 Args/Returns/Raises 모두 기술되어 있음.

2.2 _apply_loaded_state() 의 entries 루프

core.py:1356-1373

for encoded_key, entry in entries.items():
if not isinstance(entry, dict):
continue
try:
decoded_entry = self._decode_checkpoint_entry(
str(encoded_key),
entry,
)
except Exception as e:
logger.warning(
"RawBlockCore skipping invalid checkpoint entry %r: %s",
encoded_key,
e,
)
continue
if decoded_entry is None:
continue
self._index[encoded_key] = decoded_entry
  • 핵심은 try/except로 wrap한 것. 예외 발생 시 warning을 남기고 그 entry 만 스킵.
  • decoded_entry is None 분기는 invalid offset/size 인 경우(이때는 예외가 아니라 None을 반환) 처리.

2.3 회귀 테스트

test_raw_block_core.py:128-198test_raw_block_core_apply_loaded_state_skips_invalid_entry:

  • 1개의 valid entry + 2개의 malformed entry (bad-offset-entry, bad-shape-entry)로 구성된 체크포인트 state를 만든다.
  • apply_loaded_state() 호출 후:
    • valid entry 는 contains_key() True 이고, load_many_into()로 원본 payload 복원되는지 확인.
    • malformed entries 는 contains_key() False.
  • public API (apply_loaded_state, contains_key, load_many_into)만 사용하므로, coding standards §6 (encapsulation) 위반 없음.

3. Coding standards 점검

항목상태비고
SPDX 헤더Pass변경된 파일 모두 기존부터 헤더 있음
타입 힌트Pass새 헬퍼 시그니처 (str, dict[str, Any]) -> _Entry | None 명시
Any 사용Passdict value 타입은 외부 JSON 이라 Any 불가피, 적절
docstringPass새 헬퍼에 Summary/Args/Returns/Raises 모두 기술
캡슐화Pass테스트가 public API만 사용
assert 미사용Pass검증은 모두 if/raise 또는 try/except
회귀 테스트Passpartial-recovery 시나리오 1건 추가
PR scopePass단일 함수 리팩토링 + 동작 변경 + 테스트 1건. 작고 집중됨.

4. 이슈

4.1 error 이슈

없음.

4.2 warning 이슈

W1. Raises: 문구가 모호함

core.py:1246-1247

Raises:
Exception: If the entry cannot be parsed into metadata.
  • 어떤 예외가 발생하는지 불분명. 호출 측이 except Exception 으로 광범위하게 잡고 있으니 동작상 문제는 없지만, 실제로 발생할 수 있는 예외 (ValueError, TypeError, KeyError) 를 나열해주면 docstring 정확도가 올라간다.
  • 또는 호출부에서 광범위 catch 하는 의도라면 "may raise any exception while parsing untrusted checkpoint data" 같이 의도를 명시하는 것이 낫다.

W2. 광범위 except Exception 의 의도 명시

core.py:1364

  • except Exception 은 의도적이지만 (untrusted 한 디스크 데이터 복구이므로), 코드 리뷰 관점에서 넓게 잡는지 한 줄 주석 또는 docstring 보강이 있으면 좋다. 추후 누가 좁히려 할 위험을 줄임.

4.3 info 이슈

I1. malformed entry 통계 노출 고려

  • 현재는 warning log 만 남기고 끝난다. 운영 환경에서 "체크포인트 복구 시 N건 손실" 이라는 사실이 metric/status 로 노출되면 디버깅에 도움이 될 듯.
  • 예: report_status()"checkpoint_skipped_entries" 카운터를 노출하거나, _apply_loaded_state() 가 (성공 entry 수, 스킵 entry 수) 를 반환하도록 확장.
  • 이번 PR scope 를 벗어나므로 follow-up 으로 충분.

I2. 테스트의 bad-shape-entry offset 처리

test_raw_block_core.py:178

"offset": valid_offset + config.slot_bytes,
  • 이 offset 은 _is_valid_checkpoint_entry() 를 통과하는 valid offset. shape 파싱에서 예외 발생을 확인하려는 의도이며 동작은 정확함.
  • 다만 테스트 의도가 한눈에 안 보이므로 한 줄 주석 ("valid slot이지만 shape 파싱 단계에서 TypeError 발생을 테스트") 가 있으면 명확.

I3. partial-recovery 후 next_slot/free_slots 정합성

  • 테스트가 valid entry 가 살아남는 것까지는 검증하지만, 스킵된 entry 의 슬롯이 나중에 재할당 가능한지 (즉 free_slots 가 일관 상태인지) 는 검증하지 않음.
  • 현재 _apply_loaded_state() 마지막 부분 (core.py:1375-1381) 가 used_slotsself._index 로부터 다시 계산해 free list 를 정리하므로 논리적으로는 안전해 보인다. 다만 회귀 테스트가 없으니 follow-up 으로 valid entry put 후 새 key 를 put 했을 때 슬롯 충돌 없이 동작하는지 검증하면 좋다.

5. Caller impact

  • _apply_loaded_state() 의 외부 노출 함수는 apply_loaded_state() 1곳.
  • 리턴값 시맨틱 ("payload shape/layout 매칭 + 모든 valid entry 적용 시 True; per-entry record 는 invalid 면 skip") 이 변경되었다.
  • 호출자는 core.py:1491 한 곳: if not self.apply_loaded_state(data):.
    • 이전: 한 entry라도 망가지면 예외 → 호출자가 잡을 수 있는지 별개. 사실상 복구 실패.
    • 이후: malformed entry 는 무음 skip (warning log) → True 반환.
    • 즉, "이전엔 망가졌던 케이스" 가 "이제는 부분 복구 성공" 으로 처리되며, 호출자는 동일 코드로 더 관대한 결과를 받는다. breaking change 아님, 안전함.

6. 결론

  • 작고 잘 격리된 hardening PR. 헬퍼 분리 + try/except 도입 + 회귀 테스트.
  • error 0건 / warning 2건 / info 3건. 머지 가능.
  • warning 은 docstring 정확도/주석 보강 수준이라 follow-up 으로 처리해도 무방.
  • info 는 운영성 metric 노출 (I1) 정도가 가장 가치 있어 보임.

7. Severity 요약

SeverityCountKey items
error0
warning2W1: 모호한 Raises: 문구 / W2: 광범위 except Exception 의도 주석
info3I1: skipped entry 통계 노출 / I2: 테스트 의도 주석 / I3: free_slots 정합성 회귀 테스트