diff options
| author | eunhhu <[email protected]> | 2026-10-04 11:07:55 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-04 11:07:55 +0100 |
| commit | 52e51e4231f2e119c97826ae6d6e2f2af0da0c58 (patch) | |
| tree | 0f17ced79a1881bd2b67fbaa9e7ffb823f54b984 /CHECKPOINT.md | |
| parent | 420b749742badd26daf2474e9f157af17be2907f (diff) | |
| download | pure-52e51e4231f2e119c97826ae6d6e2f2af0da0c58.tar.gz pure-52e51e4231f2e119c97826ae6d6e2f2af0da0c58.zip | |
Say what apps that change on a running host showed (017 stage 3, research 115)
Changing an app in place keeps a million items' app answering but for
1.12 ms (a host restart: 150 ms; stopping and starting it again from its
store, as first built, 150.4 ms), 171.5 ms when its records change shape
(332 ms). Another app's p99 stays 0.97 times as it was while one changes
every 0.2 s; a host of one app is as it was (TPC-C +0.7%, instructions
at most +0.02%); each module change leaves 19 KB. 030 holds the windows
of both builds, the isolation, the pairs, the counts and the memory.
Diffstat (limited to 'CHECKPOINT.md')
| -rw-r--r-- | CHECKPOINT.md | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/CHECKPOINT.md b/CHECKPOINT.md index 3c53700..d179039 100644 --- a/CHECKPOINT.md +++ b/CHECKPOINT.md @@ -18,7 +18,7 @@ | HTTP 서비스 | 보기가 GET, 입력이 POST다(JSON 본문과 그 안의 그룹 객체를 제자리에서 읽는다, 라우터 코드 없음). 앱의 `send`는 이벤트와 함께 저장되고, `--send 출력=URL`로 다른 앱이나 HTTP 끝점에 순서대로 묶어 전해지며, 받는 앱은 번호마다 한 번 적용한다(서버를 죽였다 살려도 정확히 한 번). `--seal 출력=공개키`면 받는 노드의 키로 봉인해(HPKE, 전달선마다 세션 하나, 보내는 노드의 키로 인증) 사이의 중계가 읽지도 바꾸지도 못하고, 받는 노드는 `--sender 이름=키`로 보낸 이를 가린다(봉인 전달 462k/s, 봉인 없이 468k/s). 답은 저장 뒤에 나간다. 상태를 가진 앱은 소유자 스레드 하나가 입력을 적용하고, 연결 스레드는 마지막 저장의 스냅숏으로 보기를 답한다(쓰기가 동기화하는 동안에도 읽기는 기다리지 않는다) | 008 HTTP 호스트, [077](docs/research/077-apps-as-http-services.md), [080](docs/research/080-snapshot-reads.md), [082](docs/research/082-json-in-place.md), [083](docs/research/083-delivery-over-http.md), [086](docs/research/086-sealed-sends.md), [088](docs/research/088-sealed-sessions.md) | | 성능(Pi 5) | 2026-09-27, 같은 기기에서 axum·drogon과 함께 쟀다. 문서 서버(한 스레드): 64 B GET 139k/s(CPU 1초당 140k; axum 127k·63k, drogon 147k·63k), 1 MiB GET 2,362/s(axum 1,304, drogon 754), 충돌 안전 PUT은 axum-atomic의 5.1–5.8배. 앱 서비스: 내구성 있는 쓰기 64연결 21.3k/s(axum·drogon 내구 약 200/s), 합계 GET 126k/s·두 스레드 153k(axum 136k, drogon 151k), 20행 페이지 두 스레드 148k(axum 93k, drogon 138k), 쓰기와 섞인 읽기 119k/s(axum·drogon 내구 1.1–1.4k/s). 유휴 RSS 2.3 MiB(axum 2.8, drogon 10.9), 최대 3.2–5.8 MiB(axum 6.6–9.7, drogon 11.9–78.8) | [075](docs/research/075-http-host-against-axum.md), [077](docs/research/077-apps-as-http-services.md), [080](docs/research/080-snapshot-reads.md), [081](docs/research/081-tail-records.md), [087](docs/research/087-small-reads-and-idle-memory.md) | | 노드 사이 전달 | 연결 없는 링크가 기본이다(`--send 출력=pure://호스트:포트/입력`, 2026-09-29 채택). 두 노드의 키로 첫 패킷부터 봉인해 보내고 핸드셰이크가 없다. 어느 쪽을 kill -9 해도, 받는 노드의 저장소를 다른 주소로 옮겨도 다음 패킷으로 이어지며 잃거나 겹친 기록이 없다(기기 1만 개가 초당 2,000건을 보내는 중에 저장이 멈춘 100 ms 칸 0). 쉬는 링크는 받는 노드 메모리 132 B(quinn 연결의 1/289). 에폭마다 키를 바꿔 전방 비밀성을 얻는다. 전달당 CPU는 1 KiB 이상에서 quinn·ngtcp2보다 25 % 넘게 적고 61 B에서 비긴다. 손실·재정렬·병목 경로(M6)에서 재정렬 아래 quinn·ngtcp2보다 많이 나르고, 무작위 손실 아래 같으며, 깨끗한 병목에서 틀의 바이트로 3–5 % 적다. 명세가 있고, 명세만 보고 쓴 파이썬 받는 쪽이 노드와 맞붙는다. 받는 입력은 필드를 이름으로 받는다(순서가 달라도, 받는 쪽 필드가 더 있어도 되고, 보낸 필드를 버리지는 않는다). 그래서 두 노드가 함께 쓰는 보드를 한 노드씩 올려도 멈추지 않고, 기다리는 보내기도 새 필드로 옮겨진다([105](docs/research/105-growing-a-shared-board.md), [014](docs/design/014-fields-by-name.md)) | [설계 011](docs/design/011-pure-transport.md), [명세 012](docs/design/012-link-protocol.md), [093](docs/research/093-connectionless-link.md)–[102](docs/research/102-adoption-and-spec.md) | -| 여러 앱 | 한 호스트가 앱 여럿을 품는다(`pure-serve --apps`, 경로는 `/앱/…`). 앱마다 스레드를 두지 않고 정해진 실행 스레드가 차례로 돌리며, 앱마다 연결이 모이는 집 연결 스레드가 있다. 앱마다 실행량(쓴 그대로의 명령 수, 넘으면 422 `work`)·대기열(503 `busy`)·메모리 예산이 있고, 모듈이나 저장소를 열지 못한 앱은 그 앱만 멈춘다. 앱 하나에 120 KiB(프로세스 하나의 PSS의 9%), 앱 100개에도 스레드 셋. 한 앱이 몰릴 때 다른 앱의 p99는 앱마다 프로세스일 때의 0.5배, 둘 다 바쁠 때 처리량과 p99는 같다. 앱마다 보냄을 배선하고(`send=`), 링크 포트 하나가 모든 앱의 입력을 `앱/입력`으로 받는다. 같은 호스트의 앱끼리는 소켓 없이 건네 링크의 두 배(초당 114만 건)를 CPU 40%로 나른다. 링크와 전달선은 프로세스의 보내는 루프 하나가 보낸다(링크와 전달선 스무 개에 스레드 24개가 5개, 링크 +63%, 전달선 같음) | [017](docs/design/017-apps-on-one-host.md), [111](docs/research/111-apps-on-one-host.md), [112](docs/research/112-sending-between-apps.md), [113](docs/research/113-one-sending-loop.md) | +| 여러 앱 | 한 호스트가 앱 여럿을 품는다(`pure-serve --apps`, 경로는 `/앱/…`). 앱마다 스레드를 두지 않고 정해진 실행 스레드가 차례로 돌리며, 앱마다 연결이 모이는 집 연결 스레드가 있다. 앱마다 실행량(쓴 그대로의 명령 수, 넘으면 422 `work`)·대기열(503 `busy`)·메모리 예산이 있고, 모듈이나 저장소를 열지 못한 앱은 그 앱만 멈춘다. 앱 하나에 120 KiB(프로세스 하나의 PSS의 9%), 앱 100개에도 스레드 넷(연결 하나, 실행 둘, 구성 파일을 읽는 하나). 한 앱이 몰릴 때 다른 앱의 p99는 앱마다 프로세스일 때의 0.5배, 둘 다 바쁠 때 처리량과 p99는 같다. 앱마다 보냄을 배선하고(`send=`), 링크 포트 하나가 모든 앱의 입력을 `앱/입력`으로 받는다. 같은 호스트의 앱끼리는 소켓 없이 건네 링크의 두 배(초당 114만 건)를 CPU 40%로 나른다. 링크와 전달선은 프로세스의 보내는 루프 하나가 보낸다(링크와 전달선 스무 개에 스레드 24개가 5개, 링크 +63%, 전달선 같음). 달리는 호스트가 SIGHUP에 구성 파일을 다시 읽어 앱을 더하고, 멈추고, 그 자리에서 바꾼다(상태는 메모리에서 이름으로 옮긴다: 100만 항목의 앱이 1.1 ms만 쉬고, 다른 앱의 p99는 그대로) | [017](docs/design/017-apps-on-one-host.md), [111](docs/research/111-apps-on-one-host.md), [112](docs/research/112-sending-between-apps.md), [113](docs/research/113-one-sending-loop.md), [115](docs/research/115-apps-that-change.md) | | 메모리 한도 | 앱마다 상태의 예산이 있다(`--memory`). 목록의 항목, 텍스트, outbox, 들은 번호를 저장 형식의 바이트로 센다(어느 기기에서나 같다). 예산을 넘기며 늘리는 사건은 거절하고(503 `memory`) 줄이는 사건은 받는다. 받는 쪽이 늦으면 outbox가 차서 클라이언트까지 역압이 가고, 가득 찬 받는 쪽은 링크로 알려 보내는 쪽이 다시 보내지 않는다. 답(`--reply`)은 자기 보내기의 자리를 쓴다. 상태 4 MB를 준 노드는 부하 아래 상주 9.6–9.8 MiB에 멈춘다(예산 없이 30초에 45.9 MiB). 오래 붙든 스냅숏은 그때 상태 한 벌만 쥔다(전: 30초에 678 MiB) | [설계 013](docs/design/013-memory-budget.md), [104](docs/research/104-where-memory-goes.md) | | 표면과 메신저 | 사람을 위한 표면이 노드 안에서 돈다(`pure-serve --surface`): 마지막 저장의 스냅숏을 제자리에서 읽고, 친 키와 글자는 HTTP 요청과 같은 줄로 소유자에게 간다. Vega의 디스플레이·픽셀이 그 표면이다. 두 노드의 메신저(Vega `examples/messenger.aup`)는 서로에게 봉인·인증해 보내고, 한 줄이 상대 노드에 보이기까지 RAM 저장소에서 p50 0.79 ms·p99 1.1 ms, SD 카드에서 p50 3.5 ms(꼬리는 SD의 동기화) | [설계 010](docs/design/010-surfaces.md), [089](docs/research/089-messenger.md) | | 표 크기의 상태 | 목록이 영속 B+트리다(변경·키 탐색·저장본 위치 O(log n), 스냅숏 O(1), 1,600만 항목, 런타임 상태 1 GiB). pgbench의 TPC-B 같은 이체(세 표의 행과 이력, 한 트랜잭션)가 10만 계좌에서 RAM 24.5k/s(전: 3만 계좌 3.2k/s), SD 카드 내구 1,339/s(SQLite WAL FULL 84–153/s) | [090](docs/research/090-tables.md) | @@ -32,8 +32,8 @@ +9%, 상주 −10%, [107](docs/research/107-snapshot-nodes-reused.md)). 남은 가장 큰 몫은 항목 찾기다. 키로 나눈 소유자는 그다음에 본다. 대신 압축한 파일이 한 주기의 0을 미리 가져 커밋이 새 블록을 받지 않는다(저장소 커밋 +21%, 저널 커밋 −59%, [085](docs/research/085-cycle-sized-files.md)). -남은 것: macOS의 호스트(`pure-serve`는 리눅스의 것), 달리는 호스트의 앱을 더하고 바꾸기(017의 3단계), 압축을 없애는 제자리 재사용 저장소(085 다음), 응답을 기다리는 출력의 묶음 전달(083), 앱 -라우트의 인증·TLS(문서 피어의 TLS는 있다), aup·Vega의 배포 묶음, 캐시보다 큰 목록을 찾는 걸음(109: 미리 가져오기로는 줄지 +남은 것: macOS의 호스트(`pure-serve`는 리눅스의 것), 바뀐 모듈을 놓기(바꿀 때마다 19 KB, 115), 압축을 없애는 제자리 재사용 저장소(085 다음), 응답을 기다리는 출력의 묶음 전달(083), 앱 +라우트의 인증·TLS(017의 3b, 문서 피어의 TLS는 있다), aup·Vega의 배포 묶음, 캐시보다 큰 목록을 찾는 걸음(109: 미리 가져오기로는 줄지 않았다. 한 사건의 조회를 겹치거나 구조를 바꿔야 한다). ## 공개할 작업물과 완료 증거 |
