Kết xuấtvi

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.

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ểuVai tròBề mặt chính
kênhTay 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ạiCác trường: id, call, status, data, created_ms, from, trace
statusEnum đánh dấu vòng đờirequest, item, byte, bulk, done, error, cancel
gửi<T>Luồng một chiều gửi đi — gửi frame đến providerda(T), fini() → status
nhận<T>Luồng một chiều nhận vào — nhận frame từ provideraccipe(), 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") ↦ json

Việ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:

ProviderPrefixMiền I/O
chỉchỉ:*Hệ thống tệp: đọc, ghi, siêu dữ liệu, thao tác thư mục
processusprocessus:*Thực thi tiến trình: tạo, pipe, mã thoát
consolumconsolum:*I/O console: stdin, stdout, stderr
tempustempus:*Thời gian: hiện tại, ngủ, bộ định thời
aleatoraleator:*Tính ngẫu nhiên: entropy, phân phối
httphttp:*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 content

Trì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 = true

Trong 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:

RepositoryVai trò
host-kernel-rsBộ đị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-rsGắn kết native — worker, hook khởi động register_providers, tích hợp host_register.rs được sinh ra
host-providers-rsCá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ọi phâ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#

  1. radix/docs/design/frame-stream-types.md — đặc tả đầy đủ cho kênh, khung, status, gửi, nhận
  2. radix/docs/design/host-provider-gateway.md — kiến trúc bộ định tuyến mỏng, hợp đồng provider, manifest biên dịch
  3. faberlang/host-kernel-rs/ — triển khai bộ định tuyến kernel
  4. faberlang/host-native-rs/ — gắn kết và đăng ký native
  5. faberlang/host-providers-rs/ — các crate provider (chỉ, processus, consolum, tempus, aleator, http)
  6. examples/corpus/ad/ — các tệp ví dụ kênh