aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/017-apps-on-one-host.md
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-01 06:50:09 +0100
committereunhhu <[email protected]>2026-10-01 06:50:09 +0100
commit56e4a08b03d50f3afdeca7f97f6d46b50f359508 (patch)
tree250a62a5b7a9b7ceef37c3b4c29c4ccf30aec364 /docs/design/017-apps-on-one-host.md
parentb146696c7df9834fdb4288cca2e209b1ed544fe9 (diff)
downloadpure-56e4a08b03d50f3afdeca7f97f6d46b50f359508.tar.gz
pure-56e4a08b03d50f3afdeca7f97f6d46b50f359508.zip
Say how apps will send to each other and to other nodes, and what it must show (017)
Stage 2: each app of --apps takes its wiring (send=, seal=, reply=), its sends' source being APP.OUTPUT; one --link-port takes every app's inputs, a stream's input name APP/INPUT (012 unchanged); and send= OUTPUT=APP/INPUT hands an app's saved sends to another app of the same host with no socket, seal or packet: an outlet with the window links have, a batch of records as a link delivers them put in the receiving app's queue, applied after its last number heard, and the number heard after its save trimming the sender's outbox. Merging the send threads into one loop is split off as 2b. Before building: it goes in if the inner outlet stores at least as many sends a second as a loopback pure:// link between the same two apps, at half the host's CPU a stored send or less; checked by a host sending to an app of its own and to one of another host, exactly once and in order across a kill -9, and held back by a full receiver.
Diffstat (limited to 'docs/design/017-apps-on-one-host.md')
-rw-r--r--docs/design/017-apps-on-one-host.md43
1 files changed, 41 insertions, 2 deletions
diff --git a/docs/design/017-apps-on-one-host.md b/docs/design/017-apps-on-one-host.md
index 7167e2e..5f7aa7e 100644
--- a/docs/design/017-apps-on-one-host.md
+++ b/docs/design/017-apps-on-one-host.md
@@ -1,6 +1,7 @@
# 017 — 한 호스트의 여러 앱: 차례, 예산, 실패 경계
-작성일: 2026-10-01. 상태: 1단계 구현, 검사로 고정하고 쟀다([111](../research/111-apps-on-one-host.md)). 2·3단계는 설계.
+작성일: 2026-10-01. 상태: 1단계 구현, 검사로 고정하고 쟀다([111](../research/111-apps-on-one-host.md)). 2단계는 착수 기준을
+적었다. 3단계는 설계.
[외부 리뷰 004](../outside-feedback/feedback-004.md)의 "구현 방향에 대한 평가" 셋째에서 시작한다. 작은 OS의 운영 모델(
[007](007-execution-domains.md))을 Pure가 실제로 갖게 하는 단계다.
@@ -102,7 +103,7 @@ counter apps/count.pmod stores/counter
경계. 여러 앱의 구성에서 보냄(`--send`), 봉인, 답, 링크 포트, 표면은 아직 받지 않는다(앱 하나에서는 지금처럼 된다).
2. **앱 사이와 노드 사이.** 앱마다의 보냄과 답. 링크 포트 하나가 모든 앱의 입력을 받는다(스트림의 input 이름 `앱/입력`, 012의
형식은 그대로). 같은 호스트의 앱끼리는 소켓과 봉인 없이 건넨다(007: 내부 연결은 준비된 관계를 쓴다). 보냄마다의 스레드를
- 하나의 보내는 루프로 모은다.
+ 하나의 보내는 루프로 모으는 것은 2b로 뗀다(아래).
3. **앱의 수명.** 달리는 호스트에 앱을 더하고, 멈추고, 모듈을 바꾼다. 불확실해진 앱을 저장소에서 다시 연다. 앱 경로의 인증과
함께다(CHECKPOINT의 남은 것).
@@ -150,6 +151,44 @@ counter apps/count.pmod stores/counter
앱과 실행 스레드), `d95740e`(바쁜 앱은 제 실행 스레드에), `eb9a3a5`(부하 도구), `41502b9`(집 스레드), `aef14c0`(예산이 없으면
세지 않는다).
+## 2단계: 앱 사이와 노드 사이
+
+**보냄.** `--apps`의 줄이 앱마다의 배선을 받는다. `send=출력=URL`(여럿), `seal=출력=키`, `reply=출력=입력`. 뜻은 앱 하나의
+`--send`, `--seal`, `--reply`와 같다. 보낸 것의 source는 `앱.출력`이다(앱 하나에서는 `--name.출력`). 노드의 키(`--key`)와
+받을 보내는 쪽(`--sender`, `--senders`, `--sealed-only`)은 호스트의 것이다.
+
+**받기.** `--link-port` 하나가 모든 앱의 입력을 받는다. 스트림의 input 이름이 `앱/입력`이면 그 앱의 그 입력이다(보내는 쪽 URL은
+`pure://호스트:포트/앱/입력`). 012의 형식은 그대로다(이름 1–64 B 안). 멈춘 앱이나 모르는 이름은 "그 이름의 입력이 없다"(REFUSED
+1)다. HTTP 전달은 지금처럼 `/앱/inputs/입력`이다.
+
+**호스트 안의 건넴.** `send=출력=앱/입력`(스킴 없이)은 같은 호스트의 앱에 건넨다. 소켓, 봉인, 패킷이 없다.
+
+- 보내는 앱이 저장한 보냄을 출구 하나가 받는다(전달선·링크와 같은 창: 받는 쪽이 가진 것 너머로 65,536건, `--window` 바이트).
+ 보내는 앱의 차례가 저장 뒤에 그 묶음을 받는 앱의 대기열에 일감 하나로 넣는다. 링크가 넘기는 기록과 같은 꼴이다(첫 번호,
+ 건수, source, 저장된 그대로의 기록).
+- 받는 앱은 링크의 기록처럼 적용한다. 들은 번호 다음부터, 순서대로, 한 번씩이다. 저장한 뒤 들은 번호를 출구에 알린다. 보내는
+ 앱의 다음 차례가 outbox를 그만큼 다듬는다. 묶음은 출구마다 한 번에 하나만 가 있다.
+- 받는 앱의 입력이 모양이 다르면 이름으로 받는다(014): 시작할 때 `pure_module_takes`로 보고, 못 받으면 보내는 앱이 시작하지
+ 않는다. 받는 앱이 메모리 예산으로 받지 못하면(013) 묶음은 돌아오고, 100 ms 뒤에 다시 간다.
+- 재시작: 보내는 앱의 outbox에 남은 것이 다시 가고, 받는 앱의 들은 번호가 이미 받은 것을 걸러낸다(링크와 같다).
+
+**2b(뒤로 미룬다).** 보냄마다의 스레드(전달선 하나, 링크 하나에 하나씩)를 하나의 보내는 루프로 모은다. 지금 출력을 가진 앱은
+보냄마다 스레드 하나를 더한다. 앱마다 스레드를 두지 않는다는 원칙에 어긋나는 마지막 자리다.
+
+## 2단계의 착수 기준
+
+- **바꿀 결정:** 같은 호스트의 앱 사이를 링크(소켓, 봉인)가 아니라 안쪽 출구로 건넬지다. 아래를 채우지 못하면 같은 호스트의
+ 앱끼리도 `pure://`로 보낸다.
+- **최소 확인**(`tests/check.py`의 `server_apps_links`):
+ - 한 호스트의 앱이 같은 호스트의 앱(안쪽 출구, 이름으로 받는 모양 하나 포함)과 다른 호스트의 앱(`pure://…/앱/입력`)에
+ 보낸다. 모든 보냄이 한 번씩, 순서대로 도착한다. 보내는 호스트를 `kill -9`하고 다시 띄워도 잃거나 겹친 것이 없다.
+ - 받는 앱이 메모리 예산으로 가득 차면 보내는 앱의 outbox가 붙든다. 받는 앱이 비우면 이어서 간다. 잃는 것이 없다.
+ - 앱 하나의 호스트는 지금과 같다(링크, 전달, 답의 검사가 모두 초록).
+- **통과 조건:** RAM의 Pi 5에서, 한 호스트의 두 앱 사이를 안쪽 출구와 루프백 `pure://` 링크로 잰다(보내는 앱에 64연결의 쓰기,
+ 쓰기마다 보냄 하나).
+ - 받는 앱에 저장된 보냄의 초당 수가 링크보다 낮지 않다.
+ - 저장된 보냄 하나에 드는 호스트의 CPU가 링크의 절반 이하다.
+
## 하지 않는 것
- 이벤트를 중간에 멈추고 다른 앱에 넘기는 선점. 이벤트는 원자적이고 끝까지 돈다. 그 대신 실행량 예산이 한 이벤트의 길이를,