diff options
| author | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
| commit | b1ce1927022d374198441afafeb27199fc8a052a (patch) | |
| tree | 6021f175f4c67ed03b44240eaa2f90d846f12f6f /docs/research/018-native-connections.md | |
| parent | d34f9426d5317a1948f12f229439946728bc342a (diff) | |
| download | pure-b1ce1927022d374198441afafeb27199fc8a052a.tar.gz pure-b1ce1927022d374198441afafeb27199fc8a052a.zip | |
Establish native micro runtime checkpoint
Diffstat (limited to 'docs/research/018-native-connections.md')
| -rw-r--r-- | docs/research/018-native-connections.md | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/docs/research/018-native-connections.md b/docs/research/018-native-connections.md new file mode 100644 index 0000000..f2c26bc --- /dev/null +++ b/docs/research/018-native-connections.md @@ -0,0 +1,81 @@ +# 018 — 요청·DB 결과·전송의 수명을 연결한 네이티브 경로 + +> 역사적 기록: 이 문서의 SQLite 구현은 사용자 요구와 맞지 않아 +> [019의 SQL 없는 바이트 저장](019-byte-storage.md)으로 교체했다. 아래 결과와 원자료는 +> 당시 구현의 기록이며 현재 구현의 의존성·검증 결과를 뜻하지 않는다. + +2026-09-23. **기존 작성물의 저장·복원을 실제 TCP와 SQLite에 연결했다.** 한 실행기에서 +이동한 배치를 저장하고 다른 실행기에서 복원할 수 있다. 새 네이티브 서버는 브라우저 없이 +실행되며, 기존 CLI가 요청한다. 이번 결과는 실제 연결의 구현·정확성 확인이다. 속도·전체 +메모리 우위나 새 알고리즘의 증거는 아니다. + +알아낸 것은 연결의 책임 범위다. DB 결과를 응답 본문 배열로 다시 복사하지 않으려면, +전송이 끝날 때까지 원본의 수명도 이어져야 한다. 느린 수신자가 있으면 데이터뿐 아니라 +그 결과를 유지하는 DB 자원도 살아 있다. 본문 길이·동시 연결·대기 시간을 함께 제한했다. +이 방식이 복사하는 방식보다 전체적으로 유리한지는 이번 검사로 결정하지 않는다. + +## 실제 작성 흐름 + +기존 `.pure` 정의에서 도형을 움직인 뒤 CLI의 `connect`, `push 0`으로 저장한다. +빈 실행기를 열어 `connect`, `pull`하면 적용 코드·현재 값·초안이 복원된다. 서버를 재시작한 +뒤에도 남는다. 다른 실행기가 먼저 갱신하면 이전 revision의 쓰기를 거절해 덮어쓰지 않는다. +실행 방법은 [구현 README](../../prototypes/connections/README.md)에 있다. + +숫자 VM 자체에 DB나 네트워크를 넣지는 않았다. 네이티브 연결 경로는 C17로 작성했고 기존 +Node/Wasm CLI를 재사용했다. C는 현재 SQLite·POSIX 연결을 직접 확인하기 위한 구현 선택이다. +언어 선택의 성능 우위를 주장하거나 기존 Zig 코어를 다시 작성한 것이 아니다. + +## 연결에서 구현한 계약 + +| 경계 | 구현 | 실패·완료 | +|---|---|---| +| 요청 → 입력 구간 | Content-Length 확인 후 한도 안에서 할당하고 부분 수신 | 불완전한 본문은 DB에 제출하지 않고 회수 | +| 입력 구간 → DB | 같은 바이트 구간을 `SQLITE_STATIC`으로 바인드 | 모든 경로에서 statement를 먼저 해제한 뒤 입력을 회수 | +| DB 변경 → 응답 | revision 검사와 갱신을 트랜잭션으로 실행 | COMMIT 뒤에만 성공 응답; 실패·충돌은 기존 저장 내용 유지 | +| DB 결과 → 전송 | 같은 읽기 스냅샷에서 크기를 확인하고 결과 BLOB을 대여 | 별도 응답 본문 사본 없이 헤더·본문 구간을 순서대로 전송 | +| 전송 → 회수 | 부분 전송 위치와 소유자 해제 함수를 연결 | 완료·연결 오류·기한 종료에서 원본을 한 번 회수 | + +SQLite의 바인딩 규칙에 따라 입력 포인터를 statement 종료까지 유지했다. +[공식 바인딩 수명 규칙](https://www.sqlite.org/c3ref/bind_blob.html). +조회 포인터도 변환·step·reset·finalize로 무효화될 수 있으므로 전송 중에는 해당 statement를 +진행하거나 해제하지 않는다. [공식 결과 포인터 수명 규칙](https://www.sqlite.org/c3ref/column_blob.html). +본문 전송 완료는 `send`가 바이트를 받아들인 시점이다. 상대 앱의 처리 완료까지 보장하지 않는다. + +DB 커밋과 응답 전달은 별개다. 응답을 읽지 않은 클라이언트가 끊어져도 이미 끝난 커밋은 +남는다. 조건부 갱신으로 오래된 revision의 재시도를 거절하지만, 임의 RPC의 exactly-once나 +분산 트랜잭션을 제공하지 않는다. [SQLite 트랜잭션 경계](https://www.sqlite.org/lang_transaction.html). + +## 검증과 한계 + +Linux AArch64, GCC 14.2.0, SQLite 3.46.1에서 확인했다. + +- 부분 송수신, 이진 본문, 버전 충돌, DB 잠금·오류, 불완전한 요청, 다른 쓰기 중의 읽기 + 스냅샷, 수신 종료, 자원 포화·기한 종료, 실제 작성물 복원·재시작 등 **15개 통합 시나리오**. +- 코어 검사: 전송 중 조기 해제 금지·중복 회수 방지, 저장 실패 후 내용 보존, revision 소진, + 빈 본문과 읽기 예산 검사. 일반 빌드와 ASan·UBSan 빌드 모두 통과했다. +- 기존 CLI 회귀 검사 8개 통과. 복원 실패·누르고 있는 입력이 있을 때 로컬 상태와 원격 + revision이 바뀌지 않는 것도 통합 검사에 포함했다. +- 검사 종료 후 연결과 보유 본문이 모두 0이고, 본문 접수 한도와 연결 슬롯 수를 넘지 않았다. + 이는 지정한 자원의 수명·한도 검사이며 전체 RAM 상한이나 처리 성능 측정이 아니다. + +SQLite 내부 할당·복사, 페이지 캐시·WAL, OS 버퍼, 클라이언트의 직렬화 비용은 남는다. +수신 헤더에 함께 들어온 본문 접두부도 한 번 복사한다. 장기 읽기는 WAL checkpoint 진행을 +늦출 수 있어 디스크 비용도 포함한 판단이 필요하다. [SQLite WAL 읽기·checkpoint 규칙](https://www.sqlite.org/wal.html#concurrency). +DB 호출은 아직 동기식이므로 디스크 작업 중 다른 연결 처리가 지연될 수 있다. macOS 실행, +전원 장애·디스크 고장, 원격 배포, 인증·TLS, 범용 HTTP/RPC, 네이티브 UI는 검증 범위 밖이다. +동적 링크한 SQLite 자체를 sanitizer로 다시 빌드한 것은 아니다. + +[원자료·재현](../../prototypes/connections/results/2026-09-23-native-connections/README.md), +[전송 수명](../../prototypes/connections/flow.c), +[DB 연결](../../prototypes/connections/store.c), +[호스트](../../prototypes/connections/server.c), +[기존 CLI 연결](../../prototypes/workbench/remote.mjs). + +## 다음 결정 + +현재 경로와 바이트 구간의 수명은 네이티브 코드에 고정되어 있다. Pure 정의에서 이 연결을 +작성하거나 실행 준비 단계에서 불필요한 연산·전달을 제거하는 기능은 아직 없다. +다음은 **이 저장 작업의 입력·검증·외부 효과·응답 관계를 실행 가능한 연결 정의로 분리하는 것**이다. +기존 문법·숫자 VM을 그대로 강제하지 않고, 외부 효과를 재계산하거나 롤백했다고 잘못 표현하지 +않도록 범위를 정한다. 소비자의 요구와 수명에서 판단 가능한 전달 비용부터 다룬다. +새 DB·RPC 기능을 병렬로 늘리거나 종료한 공유/복사 벤치마크를 다시 실행하지 않는다. |
