fix(summarize): map_results persist aliasing — 유닛 스냅샷 소급 오염으로 UPDATE 스킵
60254 라이브 E2E 에서 발견: 완주는 성공했으나 payload.presegment.map_results 에 unit 0 만 persist. 원인 = map_results dict 를 in-place 변경 → 직전 commit 의 SQLAlchemy committed 스냅샷이 같은 중첩 객체를 참조 → old==new 판정 → 2번째 commit 부터 UPDATE 스킵. 멱등 재개 시 완료 유닛 재호출 비용 발생(정확성 무영향). fix = 매 유닛 map_results/preseg/payload 전부 새 dict 재구성(공유 참조 0). test = FakeSession 이 commit 시점 payload 객체 참조를 박제, 사후 직렬화로 스냅샷 유닛 수가 1..n 단조 증가 단정 — 구 코드에 대해 FAILED 네거티브 검증 완료. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -387,22 +387,29 @@ async def _process_map_reduce(
|
||||
f"({perr}) — 유닛 재시도 대상"
|
||||
)
|
||||
continue
|
||||
map_results[key] = {
|
||||
"index": unit.index,
|
||||
"titles": [t for t in unit.section_titles if t][:8],
|
||||
"tldr": out.tldr,
|
||||
"detail": out.detail,
|
||||
"inconsistencies": _filter_inconsistencies(out.inconsistencies or []),
|
||||
# ★매 유닛 새 dict 로 재구성 (in-place 변경 금지) — 직전 commit 의 committed
|
||||
# 스냅샷이 같은 중첩 객체를 참조하면 old==new 로 보여 SQLAlchemy 가 UPDATE 를
|
||||
# 스킵한다(60254 라이브에서 unit 0 만 persist 된 aliasing 버그의 fix).
|
||||
map_results = {
|
||||
**map_results,
|
||||
key: {
|
||||
"index": unit.index,
|
||||
"titles": [t for t in unit.section_titles if t][:8],
|
||||
"tldr": out.tldr,
|
||||
"detail": out.detail,
|
||||
"inconsistencies": _filter_inconsistencies(out.inconsistencies or []),
|
||||
},
|
||||
}
|
||||
preseg.update({
|
||||
preseg = {
|
||||
**preseg,
|
||||
"tier": plan.tier,
|
||||
"over_pct": plan.over_pct,
|
||||
"total_est_tokens": plan.total_est_tokens,
|
||||
"units": n,
|
||||
"map_results": map_results,
|
||||
})
|
||||
payload["presegment"] = dict(preseg)
|
||||
queue_row.payload = dict(payload) # 재할당 = JSONB 변경 감지
|
||||
}
|
||||
payload = {**payload, "presegment": preseg}
|
||||
queue_row.payload = payload # 재할당 = JSONB 변경 감지
|
||||
await session.commit() # 유닛 단위 멱등 재개 지점
|
||||
|
||||
if failed_units:
|
||||
|
||||
Reference in New Issue
Block a user