Capabilities and frames
Ranh giới giữa Faber và mọi cách mà một hệ điều hành có thể triển khai I/O.
gọi là nguyên thủy gọi capability cấp thấp của Faber — ranh giới
giữa mã Faber và thế giới bên ngoài. Nó mở một cuộc hội thoại có kiểu
(kênh) với tài nguyên máy chủ được xác định bằng chuỗi route, sau đó
trao đổi các frame có cấu trúc (khung) qua các luồng một chiều.
Kernel máy chủ phân phối mỗi route đến một crate provider có thể cắm,
crate này triển khai I/O thực tế — hệ thống tệp, mạng, console, thời gian,
tính ngẫu nhiên hoặc bất kỳ khả năng nào khác mà hệ điều hành cung cấp.
Nguyên thủy gọi#
gọi là một từ khóa, không phải một hàm. Nó mở một cuộc hội thoại
không trong suốt với route được đặt tên bằng một literal ascii và dữ liệu
mở tùy chọn:
# Simple materialized call: open, send opener, drain response
hằng văn_bản content ← gọi 'solum:lege' ("config.toml") ↦ văn_bản
# Typed conversation handle for streaming interaction
hằng kênh s ← gọi 'processus:curre' ("ls", ["-la"])Chuỗi route tuân theo mẫu prefix:verb. Kernel máy chủ
chỉ đối sánh prefix — provider sở hữu mọi verb dưới prefix đó:
solum:lege ─┐
solum:modum ─┼─► prefix "solum" ──► chỉ provider crate
solum:vincula─┘gọi không phải là một giao diện gọi hàm ngoại. Nó không gọi các hàm C,
không tải thư viện động và không nhúng hợp ngữ nội tuyến. Đây là một ranh
giới truyền thông điệp có cấu trúc: Faber gửi các frame có kiểu và nhận
các frame có kiểu, mà không cần biết provider được triển khai bằng Rust,
chạy trong cùng tiến trình, ủy quyền cho một system call hay chuyển tiếp
đến một máy chủ từ xa.
Các kiểu frame#
Năm kiểu do trình biên dịch sở hữu tạo thành hệ thống frame:
| Kiểu | Vai trò | Bề mặt chính |
|---|---|---|
kênh | Tay cầm cuộc hội thoại — một trao đổi hai chiều đang diễn ra | Được tạo bởi gọi; được rút cạn qua ↦ T hoặc tách thành các view |
khung<T> | Bao frame — một thông điệp có cấu trúc trong cuộc hội thoại | Các trường: id, call, status, data, created_ms, from, trace |
status | Enum đánh dấu vòng đời | request, item, byte, bulk, done, error, cancel |
gửi<T> | Luồng một chiều gửi đi — gửi frame đến provider | da(T), fini() → status |
nhận<T> | Luồng một chiều nhận vào — nhận frame từ provider | accipe(), con_trỏ(), exhauri(), fini() |
Sử dụng các view định hướng#
# Open a conversation, get directional views
hằng kênh s ← gọi 'solum:scribe' ("output.txt")
hằng gửi<văn_bản> out ← s.meus<văn_bản>()
hằng nhận<văn_bản> input ← s.tuus<văn_bản>()
# Send content frames
out.da("line one")
out.da("line two")
out.fini()
# Read response frames
lặp từ input.cursor() hằng frame {
ghi_chú frame.data
}
hằng status inbound ← input.fini()Vật chất hóa đơn giản#
Với trường hợp phổ biến — mở, gửi dữ liệu mở và rút cạn tất cả frame
phản hồi thành một giá trị — kênh ↦ T thu gọn cuộc hội thoại:
# Read a file: open + drain into văn_bản
hằng văn_bản body ← gọi 'solum:lege' ("config.toml") ↦ văn_bản
# Parse JSON from an HTTP response
hằng json data ← gọi 'http:peti' ("https://api.example.com/data") ↦ jsonViệc vật chất hóa sử dụng một bộ thu định hướng theo kiểu: ↦ văn_bản
nối tất cả frame nhận vào, ↦ json phân tích payload đã nối,
còn ↦ danh_sách<T> thu thập các frame vào một danh sách.
Provider máy chủ#
Các nhóm hiệu ứng được triển khai dưới dạng các crate provider riêng
trong faberlang/host-providers-rs. Mỗi provider sở hữu mọi verb dưới
prefix của mình:
| Provider | Prefix | Miền I/O |
|---|---|---|
chỉ | chỉ:* | Hệ thống tệp: đọc, ghi, siêu dữ liệu, thao tác thư mục |
processus | processus:* | Thực thi tiến trình: tạo, pipe, mã thoát |
consolum | consolum:* | I/O console: stdin, stdout, stderr |
tempus | tempus:* | Thời gian: hiện tại, ngủ, bộ định thời |
aleator | aleator:* | Tính ngẫu nhiên: entropy, phân phối |
http | http:* | Client HTTP (Tier D, khi được hợp nhất) |
Các provider là những crate riêng với các dependency riêng — chỉ
không kéo theo HTTP, còn http không kéo theo mã hệ thống tệp.
Mỗi provider xuất một hàm register() mà manifest máy chủ được sinh ra
sẽ gọi khi khởi động.
Ngăn xếp lớp#
Faber source: gọi 'solum:lege' (path) ↦ văn_bản
Compiler: kênh open + generic attach (no provider crate names)
Runtime: HostDispatch + conversation protocol (faber-runtime)
Kernel: route(frame) → provider for prefix
Provider: chỉ provider reads file, returns contentTrình biên dịch sinh ra cơ chế phân phối tổng quát — nó không bao giờ
nhúng tên crate provider vào mã được sinh. Runtime cung cấp
HostDispatch và giao thức cuộc hội thoại. Kernel (từ
host-kernel-rs) định tuyến frame đến provider thích hợp dựa trên prefix.
Provider (từ host-providers-rs) thực hiện I/O thực tế.
Điều này có nghĩa là mã Faber được sinh ra trung lập với provider. Cùng một binary đã biên dịch có thể liên kết với các triển khai provider khác nhau — provider hệ thống tệp thực cho môi trường production, provider mô phỏng cho việc kiểm thử — bằng cách thay đổi manifest biên dịch.
Manifest biên dịch#
Các provider cần liên kết được kiểm soát bởi manifest biên dịch được sinh
ra và bảng [dispatch] trong faber.toml:
[target.rust]
host = "native"
[dispatch]
providers = ["solum", "processus", "consolum", "tempus", "aleator"]
[dispatch.providers.http]
enabled = trueTrong quá trình biên soạn, provider bị thiếu sẽ tạo lỗi runtime
E_NO_ROUTE. Trong chế độ nghiêm ngặt (tương lai), mọi prefix gọi trong
chương trình phải xuất hiện trong manifest biên dịch, và trình biên dịch
sẽ xác thực rằng manifest capability của provider bao phủ các route được
sử dụng.
Kiến trúc#
Nền tảng máy chủ được chia thành ba repository trong tổ chức
faberlang:
| Repository | Vai trò |
|---|---|
host-kernel-rs | Bộ định tuyến mỏng — sở hữu Frame, Conversation, vòng đời kết thúc, phân phối theo prefix, lỗi có cấu trúc (E_NO_ROUTE), tổng hợp manifest capability |
host-native-rs | Gắn kết native — worker, hook khởi động register_providers, tích hợp host_register.rs được sinh ra |
host-providers-rs | Các triển khai provider — Cargo workspace với các crate theo từng họ (chỉ, processus, v.v.) |
Mỗi crate provider sở hữu các dependency native của riêng mình. Provider
http chỉ kéo hyper và tokio khi HTTP được bật. Provider chỉ
sử dụng các API tệp tiêu chuẩn và không có thêm dependency mạng.
Cùng route, mọi máy chủ. Vì
gọiphân phối dựa trên chuỗi route và provider có thể cắm, cùng một mã nguồn Faber có thể nhắm đến một binary native (host-native-rs), một runtime WASM (kernel máy chủ làm bộ chuyển đổi Frame/Wasm) hoặc một tiến trình TypeScript Node.js (host-providers-ts) mà không cần thay đổi một dòng mã Faber nào.
Bao bọc Norma#
Phần lớn mã Faber không gọi trực tiếp gọi. Thư viện chuẩn Norma
bọc các route gọi phổ biến trong các hàm có kiểu:
# Norma wraps gọi in typed, reviewed functions
hàm đọc(văn_bản thông_qua) → văn_bản {
trả gọi 'solum:lege' (thông_qua) ↦ văn_bản
}
hàm viết(văn_bản thông_qua, văn_bản content) → trống {
hằng trống _ ← gọi 'solum:scribe' (thông_qua, content) ↦ trống
}
hàm curre(văn_bản command, danh_sách<văn_bản> args) → văn_bản {
trả gọi 'processus:curre' (command, args) ↦ văn_bản
}Các hàm wrapper này cung cấp an toàn kiểu, tài liệu và xử lý lỗi mà không
che giấu sự thật rằng I/O đi qua ranh giới gọi. Các wrapper Norma là mã
nguồn mở và nằm dưới norma/src/.
Tài liệu tham khảo#
radix/docs/design/frame-stream-types.md— đặc tả đầy đủ cho kênh, khung, status, gửi, nhậnradix/docs/design/host-provider-gateway.md— kiến trúc bộ định tuyến mỏng, hợp đồng provider, manifest biên dịchfaberlang/host-kernel-rs/— triển khai bộ định tuyến kernelfaberlang/host-native-rs/— gắn kết và đăng ký nativefaberlang/host-providers-rs/— các crate provider (chỉ, processus, consolum, tempus, aleator, http)examples/corpus/ad/— các tệp ví dụ kênh