diff options
Diffstat (limited to 'docs/design')
| -rw-r--r-- | docs/design/017-apps-on-one-host.md | 43 |
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가 링크의 절반 이하다. + ## 하지 않는 것 - 이벤트를 중간에 멈추고 다른 앱에 넘기는 선점. 이벤트는 원자적이고 끝까지 돈다. 그 대신 실행량 예산이 한 이벤트의 길이를, |
