aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/048-immutable-read-write-overlap.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/research/048-immutable-read-write-overlap.md')
-rw-r--r--docs/research/048-immutable-read-write-overlap.md56
1 files changed, 56 insertions, 0 deletions
diff --git a/docs/research/048-immutable-read-write-overlap.md b/docs/research/048-immutable-read-write-overlap.md
new file mode 100644
index 0000000..469ef0d
--- /dev/null
+++ b/docs/research/048-immutable-read-write-overlap.md
@@ -0,0 +1,56 @@
+# 048 — 저장 쓰기 중에도 기존 문서를 읽는 선택형 호스트
+
+[046](046-optional-async-document-http.md)의 선택형 HTTP 호스트는 파일 효과를
+작업자 하나에 넘겨 이벤트 루프를 보호했다. 다만 쓰기가 `fsync`에서 멈추면 다른
+문서 읽기도 그 작업자 뒤에서 대기했다. 저장소 코드를 확인하면 읽기는 파일 버전을
+열어 불변 `mmap`으로 유지하고, 쓰기만 임시 파일 번호와 `.writer.lock`을 사용한다.
+따라서 **읽기 작업자 하나와 쓰기 작업자 하나**를 두되, 기존의 쓰기 직렬화는
+유지하는 경계가 가능하다.
+
+선택형 `PURE_HTTP_ASYNC` 호스트에서 두 작업자는 입력 종류에 따라 공유된
+최대 8개 작업 슬롯을 탐색한다. 각 작업자의 스택 크기는 128 KiB로 설정했다.
+HTTP 연결과 `pure_runtime_complete()`는 기존처럼 소유 스레드에서 처리한다.
+기본 코어·CLI·HTTP에는 이 작업자들이 링크되지 않는다. 새 앱 모델이나 공용
+코어 연산은 추가하지 않았다.
+
+[결정적 HTTP 검사](../../prototypes/connections/results/2026-09-24-async-read-write/gated.json)는
+실제 CLI로 `gated=old` 버전 1을 만든 뒤, HTTP 수정 `oldafter`를 파일 동기화
+직전에 멈춘다. 쓰기를 풀기 **전에** 같은 문서의 GET이 `old`, ETag `"1"`을
+반환한다. 이때 잘못된 다른 HTTP 요청도 400으로 답하고, 쓰기를 기다린 연결은
+기한에 닫힌다. 쓰기를 풀면 GET이 `oldafter`, ETag `"2"`를 반환한다. 종료 중인
+별도 실행에서도 진행 중인 쓰기 완료를 기다리고 종료 시 보유 본문은 0 B다.
+이 검사는 한 작업자로 모든 파일 효과를 실행하던 호스트에서는 통과하지 않는다.
+[ASan·UBSan 실행](../../prototypes/connections/results/2026-09-24-async-read-write/sanitized.json)과
+[기존 HTTP 정확성 전체 검사](../../prototypes/connections/results/2026-09-24-async-read-write/full-check.json)도
+통과했다.
+
+[서비스 작업 원자료](../../prototypes/connections/results/2026-09-24-async-read-write/service-scale.json)는
+고정 정의·소스 정의·선택형 비동기 소스 정의로 각각 8 KiB 문서 1,024개를
+만들고 8개 클라이언트가 4,096개 요청을 처리한 결과다. 세 호스트의 최종 문서
+해시와 저장 파일 수가 같고, 모두 보유 본문 0 B로 종료했다. 이 실행의 비용은
+다음과 같다.
+
+| Linux AArch64 / GCC 14 | 기본 소스 HTTP | 선택형 읽기+쓰기 HTTP |
+|---|---:|---:|
+| 링크된 `text` | 43,778 B | 48,401 B |
+| 서버 구조체 | 41,528 B | 43,320 B |
+| 유휴 RSS | 1,520 KiB | 1,552 KiB |
+| 피크 RSS | 1,696 KiB | 1,728 KiB |
+| 유휴 가상주소 공간 | 2,464 KiB | 2,848 KiB |
+| 피크 가상주소 공간 | 2,528 KiB | 2,928 KiB |
+| 프로세스 스레드 | 1 | 3 |
+
+선택형 호스트는 기본 호스트보다 코드 4,623 B, 구조체 1,792 B, 이 작업의
+피크 RSS 32 KiB가 더 든다. [이전 단일 작업자 기록](046-optional-async-document-http.md)과
+비교하면 `text` 504 B와 구조체 96 B가 늘었다. 두 128 KiB 스택은 코드 섹션
+크기에 포함되지 않는다. [크기 상한](../../prototypes/connections/results/2026-09-24-async-read-write/profile.json)은
+기존 선택형 48 KiB 상한을 올리지 않고 통과했다. `make check-release`에서도
+기본 코어 `text` 5,932 B, 기본 소스 HTTP `text` 43,778 B를 유지했다.
+
+이는 **느린 쓰기와 기존 버전 읽기의 독립성 및 스냅샷 정확성**에 대한 결과다.
+읽기끼리, 쓰기끼리는 각각 직렬이며, 기한이 지난 쓰기도 취소되지 않고 커밋될
+수 있다. 매핑되지 않은 파일 캐시와 커널 소켓 버퍼는 프로세스 RSS 표에 포함되지
+않는다. 이 작업은 처리량이나
+Kitex급 RPC 성능을 측정하지 않는다. 일반 네트워크·UI 효과까지 같은 완료 모델에
+연결하려면 저장소형 `READ/WRITE/SPLICE` 계약에서 벗어나는 별도 설계와 앱 검증이
+필요하다.