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.

ad 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 (sermo) 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 (scrinium) 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.

ad 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
fixum textus content ← ad 'solum:lege' ("config.toml") ↦ textus

# Typed conversation handle for streaming interaction
fixum sermo s ← ad '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"  ──►  solum provider crate
solum:vincula─┘

ad 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
sermoTay cầm cuộc hội thoại — một trao đổi hai chiều đang diễn raĐược tạo bởi ad; được rút cạn qua ↦ T hoặc tách thành các view
scrinium<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
meus<T>Luồng một chiều gửi đi — gửi frame đến providerda(T), fini() → status
tuus<T>Luồng một chiều nhận vào — nhận frame từ provideraccipe(), cursor(), exhauri(), fini()

Sử dụng các view định hướng#

# Open a conversation, get directional views
fixum sermo s ← ad 'solum:scribe' ("output.txt")
fixum meus<textus> out ← s.meus<textus>()
fixum tuus<textus> input ← s.tuus<textus>()

# Send content frames
out.da("line one")
out.da("line two")
out.fini()

# Read response frames
itera ex input.cursor() fixum frame {
    nota frame.data
}
fixum 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ị — sermo ↦ T thu gọn cuộc hội thoại:

# Read a file: open + drain into textus
fixum textus body ← ad 'solum:lege' ("config.toml") ↦ textus

# Parse JSON from an HTTP response
fixum json data ← ad '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: ↦ textus nối tất cả frame nhận vào, ↦ json phân tích payload đã nối, còn ↦ lista<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
solumsolum:*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 — solum 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:     ad 'solum:lege' (path) ↦ textus
Compiler:         sermo open + generic attach (no provider crate names)
Runtime:          HostDispatch + conversation protocol (faber-runtime)
Kernel:           route(frame) → provider for prefix
Provider:         solum 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 ad 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ọ (solum, 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 hypertokio khi HTTP được bật. Provider solum 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ủ.ad 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 ad. Thư viện chuẩn Norma bọc các route ad phổ biến trong các hàm có kiểu:

# Norma wraps ad in typed, reviewed functions
functio lege(textus via) → textus {
    redde ad 'solum:lege' (via) ↦ textus
}

functio scribe(textus via, textus content) → vacuum {
    fixum vacuum _ ← ad 'solum:scribe' (via, content) ↦ vacuum
}

functio curre(textus command, lista<textus> args) → textus {
    redde ad 'processus:curre' (command, args) ↦ textus
}

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 ad. 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 sermo, scrinium, status, meus, tuus
  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 (solum, processus, consolum, tempus, aleator, http)
  6. examples/corpus/ad/ — các tệp ví dụ sermo