aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-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가 링크의 절반 이하다.
+
## 하지 않는 것
- 이벤트를 중간에 멈추고 다른 앱에 넘기는 선점. 이벤트는 원자적이고 끝까지 돈다. 그 대신 실행량 예산이 한 이벤트의 길이를,