aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 22:56:32 +0100
committereunhhu <[email protected]>2026-09-26 22:56:32 +0100
commit42021a500d19dbe091075338d1a621498a81f167 (patch)
treeee3e2df5f0d1ba20ef5d681bf67a148d8c896b03 /docs
parentd2adae5deacc1545cd5dbdfcc5b80697c91dac09 (diff)
downloadpure-42021a500d19dbe091075338d1a621498a81f167.tar.gz
pure-42021a500d19dbe091075338d1a621498a81f167.zip
Snapshot an app's saved states for readers on other threads
Right after a save, pure_app_snapshot makes a read-only snapshot of the saved states: numbers are copied, text states are frozen drafts that share the store mapping (pure_draft_freeze, no copy), and lists are copies of their item pointers that share the items. An unchanged list shares the last snapshot's copy. pure_app_read binds a reader app on another thread to a snapshot so the existing view functions read it. A shared item never changes again: a list stamps each item with its share count, copies a shared item it changes, and retires shared items it lets go instead of freeing them. Snapshots form a chain that goes oldest first, and items retired while a snapshot was the newest go with it. References are atomic and may be released on any thread. test-module checks that each snapshot equals the app, that kept snapshots stay as made through changes, removals, a module switch, the app stopping and the store closing, that a failed save's snapshot equals the one before, and that two threads read the newest snapshots while the app goes on (also under ASan, UBSan and LeakSanitizer).
Diffstat (limited to 'docs')
-rw-r--r--docs/design/008-module-format.md11
1 files changed, 11 insertions, 0 deletions
diff --git a/docs/design/008-module-format.md b/docs/design/008-module-format.md
index 1c4d397..be658dd 100644
--- a/docs/design/008-module-format.md
+++ b/docs/design/008-module-format.md
@@ -237,6 +237,14 @@ text·리스트가 남을 때만 위치를 유지한다.
한 번에 194 ms. `pure-run --store 경로 --batch N`으로 잰다.
- **교체.** 모듈을 바꾸면 새 상태는 저장된 값이 있으면 그것으로 시작하고, 버린 상태의 저장본은 그대로 남는다.
새 모듈의 상태는 다음 이벤트나 저장에서 공개된다.
+- **스냅숏(다른 스레드의 읽기).** 저장 직후 `pure_app_snapshot`은 저장된 상태의 읽기 전용 스냅숏을 만든다. 수·커서·
+ 인덱스는 복사하고, text 상태는 저장소 매핑의 그 버전을 가리키는 얼린 draft(`pure_draft_freeze`, 복사 없음)로,
+ 리스트는 항목을 공유하는 사본(항목 포인터 배열만 복사, 바뀌지 않은 리스트는 앞 스냅숏의 사본)으로 둔다. 공유된 항목은
+ 다시 바뀌지 않는다. 앱은 그런 항목을 바꿀 때 복사하고, 놓은 항목은 그것을 볼 수 있는 스냅숏이 모두 사라진 뒤에
+ 해제한다(스냅숏은 다음 것을 붙잡는 사슬이라 오래된 것부터 사라진다). `pure_app_read`는 다른 스레드의 읽기용 앱을
+ 스냅숏에 묶어 보기 함수를 그대로 쓰게 한다. 참조는 어느 스레드에서나 놓는다. 저장을 기다리는 변경이 있거나 text가
+ 저장소에 다 있지 않으면(상태를 맡는 저장 호스트 없음) 만들지 않는다. Pi 5에서 항목 1,024개 리스트의 스냅숏은
+ 1.2 µs, 65,536개는 87 µs다([연구 080](../research/080-snapshot-reads.md)).
검증(`test-module`): 같은 무작위 이벤트열을 메모리 앱과 수시로 재시작하는 저장 앱에 주어 매 단계 상태가 비트 단위로
같다(리스트 앱·text 앱 각 400단계, 재시작 20회 이상). 수·text·리스트를 한꺼번에 바꾸는 이벤트 중 커밋의 모든 단계에서
@@ -245,6 +253,9 @@ text·리스트가 남을 때만 위치를 유지한다.
무작위로 저장하고 가끔 저장 없이 멈췄다 다시 시작하는 저장 앱이 매 단계 같다(리스트·text 앱 각 600단계). 묶음 저장이
실패하면 묶음 전체가 되돌려지고, 저장 중 프로세스가 죽으면 묶음 전체가 남거나 전혀 남지 않는다. 비용(Pi 5, SD의 ext4): 저장하는 이벤트 하나에 약 10.6 ms가
더 든다. 대부분 두 번의 `fsync`다. 300항목 리스트에서 인덱스 이동 한 번은 파일을 약 220 B 키운다(압축 전).
+스냅숏은 저장마다 만든 것이 앱과 같고(상태와 모든 보기), 붙잡아 둔 옛 스냅숏은 항목이 바뀌고 지워지고 모듈이 바뀌고
+앱이 멈추고 저장소가 닫힌 뒤에도 만들 때 그대로다. 실패한 저장 뒤의 스냅숏은 실패 전과 같다. 두 스레드가 최신
+스냅숏을 읽는 동안 앱이 계속 적용한다(ASan·UBSan·LeakSanitizer 빌드 포함).
## HTTP 호스트 (`pure-serve`)