The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.6 KiB
2.6 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, verifiedOn
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | verifiedOn |
|---|---|---|---|---|---|---|---|---|
| REFERENCE | claim-with-a-conditional-update-not-a-read | 조건부 update로 행을 claim하고 읽은 값으로 판단하지 않는다 | fileserver-state-and-fencing | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | reference:claim-with-a-conditional-update-not-a-read |
조건부 update로 행을 claim하고 읽은 값으로 판단하지 않는다
목적
읽기와 행동 사이에 상태가 바뀌어, 이미 유효하지 않은 판단으로 되돌릴 수 없는 작업을 수행하는 것을 막는다.
규칙
-
읽고 나서 판단하지 않는다 조건을 갱신문의 where 절에 넣고 갱신 건수로 판단한다.
-
되돌릴 수 없는 작업 앞에서는 특히 그렇다 물리 삭제나 외부 호출은 되돌릴 수 없다. 그 앞의 판단은 원자적이어야 한다.
-
양쪽이 같은 사실을 본다 한쪽은 리스의 부재를 보고 다른 쪽은 만료만 보면, 둘 다 자기 기준으로 옳으면서 서로 어긋난다.
-
상태를 명시적으로 만든다 끝났다는 사실이 값으로 없으면 각 참여자가 그것을 추론하고, 추론의 근거가 서로 다르다.
-
청구하지 못하면 미룬다 갱신 건수가 0 이면 다른 참여자가 그 행을 들고 있다는 뜻이다. 강제하지 않고 다음 주기로 넘긴다.
적용 조건
여러 참여자가 같은 자원을 놓고 경합하는 정리 작업과 배치
물리 삭제나 외부 호출이 뒤따르는 판정
예외
읽기와 행동이 같은 트랜잭션 안에서 행 잠금과 함께 일어나면 조건부 갱신 없이도 안전하다. 그 잠금이 실제로 걸리는지 확인해야 한다.
예시
정리가 쓰기 리스를 읽어 없음을 확인하고 스테이징 바이트를 지웠다. 읽기와 삭제 사이에 쓰기 작업자가 그 리스를 얻었고, 지워진 것은 업로드가 이어 쓰고 있던 객체였다.
수정 후 정리는 조건부 갱신으로 청구하고, 리스가 실제로 걸려 있으면 아무것도 청구하지 않고 미룬다.
관계
- cleanup이 읽은 lease와 삭제 사이에 writer가 그 lease를 얻을 수 있었다 이 규칙을 만든 사례다.
- CAS 튜플을 where 절에 전부 반복하고 update count를 답으로 쓴다 같은 규칙의 상태 기계 판이다.
- 시간은 DB에서, 그리고 행을 잠근 다음에 읽는다 같은 계열의 짝 규칙이다.