RFC-0235:元件字典 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 將字典類型引入元件架構的提案,以用於能力整合。 |
問題 | |
毛皮變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2023-10-16 |
摘要
這個 RFC 提議提出執行階段和宣告式 API 建立及轉送功能組合 (稱為「字典」)。
提振精神
目前元件架構僅支援「指向點」轉送 為了將能力 C 從元件 A 轉送到 B 元件,每個中繼元件都必須有路徑片段,才能轉送 C。
在許多使用案例中,將路徑轉送到 將多項功能視為單一邏輯單元如果沒有這項功能 客戶必須改用昂貴、缺乏彈性和 極硬以下列舉幾個應用實例:
- 診斷功能,例如
LogSink
、InspectSink
和追蹤記錄 幾乎每個元件都會用到這個供應器,這樣就可以簡化 明顯無法轉送拓撲 fuchsia.debugdata.Publisher
等分析器功能 都屬於診斷功能,只是啟用了 某些版本目前還沒有完善的方式可以設定建構作業 新增需要橫跨整個拓撲的能力這是 是因為今天,測試運作範圍才會啟用原因分析器。- 測試領域 Proxy 會向測試用於測試的測試案例公開介面 執行測試中的元件目前這是自訂介面 與元件連線 API 十分類似這個介面 可與測試領域 Proxy 的功能替換 如此一來,測試領域 Proxy 就不必 自行定義抽象層 功能,供測試使用
- 任何位置都會透過多層轉送
但分為以下兩者:
session_manager
:從core
轉送到 「session_manager
」必須重新規劃路線「session_manager.cml
」。這是 功能眾多,難以維護 非平台功能外洩至session_manager.cml
chromium
:Chromium cml 檔案含有大量重複項目, 這樣就能輕鬆將功能分組,並轉送到 一個名稱https://fxbug.dev/42072339)
- 元件架構環境是 擷取執行器和 可將解析器設為使用 並隱含轉送到整個子樹狀結構如果我們可以用 但為了完成這項工作 並緩解元件架構轉送 API 的其餘部分 以環境為基礎的隱含轉送功能最低權限問題。
下列是能力統合的應用情境, 但除了考量到 這個 RFC 的提案內容
- 某些特定板機的驅動程式想公開自訂服務,
專為平台定義的不同定義這些服務應該由
bootstrap
領域,因為所有驅動程式庫元件都存在,但並非如此 因此最好在平台拓撲中明確命名這些元件三 如果 XML 能將這些服務組合成組合,就能處理上述問題。 - 使用
driver_test_realm
的測試出現類似問題。這些測試 將不同服務從驅動程式庫轉送至測試。在這些測試中 驅動程式庫測試領域元件會位於驅動程式和測試之間 我們希望能在這些測試中,重複使用驅動程式庫測試運作領域 而無需修改
最後,目前已有幾種現有的元件架構 API 包括分組功能但這些是各自獨立的,僅適用於 判斷這些情況以下是一些例子:
- 命名空間是所有
轉送至計畫的功能 (在其
use
宣告中)。 - 公開目錄是一組 的功能,也就是能將元件轉送至父項的路徑,也就是 存取 API
- 服務功能是一種分組方式 可將通訊協定和服務功能本身分組 進而形成「匯總」服務功能
我們有這麼多 API 提示,使用者 可定義自己的字典和路徑 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件
相關人員
根據用途,下列團隊已識別為利害關係人 :
- 建築
- 診斷
- 測試
- 工具鏈
- 驅動程式架構
- 安全性
講師:hjfreyer@
審查者:
- abarth@ (架構)
- crjohns@ (測試)
- Markdittmer@ (安全性)
- miguelfrde@ (診斷)
- surajmalhotra@ (駕駛)
- ypomortsev@ (元件架構)
諮詢:
- phosek@
- kjharland@
- 阿米特塔@
- wittrock@
- novinc@
社交功能:
符合本 RFC 的兩份內部文件:使用案例與需求文件 以及核心設計文件這些文件已獲得非正式核准, 利害關係人
這些文件中的資訊已納入此 RFC,其中 以及相關內容
需求條件
這些是「必須」支援的作業字典 分析用途並從現有的分組 API 中一般化:
- 第一級:字典是 CF API 中一流的概念。 應以能力表示。
- 匯總:系統會選取「匯總」可用來建構字典 當中包含一系列功能
- 擷取:經過「擷取」擷取個別事件的 能夠轉送及使用字典能力,就像任何一樣 技術。這大致是匯總的相反詞。
- 委派:可在元件之間傳送字典。
- 巢狀結構:由於字典是一種能力,因此字典可以包含 其他字典中
- 結構:字典會標上中繼資料,方便指明 容器有哪些功能
- 擴充功能:有一個作業可以建構新的字典
B'
, 繼承B
的內容,並新增其他功能。 - 易用性:字典內容可能會隨時間改變。不過 可能會存在限制對內容的可變動性 專屬於您的字典
設計
定義
字典的定義為一包鍵/值組合的包,其中鍵為
功能名稱 (例如fuchsia.example.Echo
),而值是 CF
技術。
「功能名稱」是指一或多個序列
字元集 [A-Za-z0-9_-.]
,大小為 1 到 N (目前 N = 100,
我們日後可能會擴大這項功能的適用範圍。
執行階段的字典
我們將引入一個公用 FIDL 通訊協定,為 字典中。作為 FIDL-虛擬程式碼:
library fuchsia.component;
type DictionaryEntry = resource struct {
key DictionaryKey;
value Capability;
};
protocol Dictionary {
Insert(DictionaryEntry) -> ();
Remove(DictionaryKey) -> (Capability);
Lookup(DictionaryKey) -> (Capability);
Enumerate() -> Iterator<DictionaryKey>;
Clone();
};
我們也將推出可公開搜尋的 FIDL 通訊協定, 呼叫端來建立空白字典。
後續設計工作會決定
Capability
。
元件宣告中的字典
我們先從一些正式程序開始,以便定義 作業。我們要定義四個 元件:元件輸入字典、元件輸出字典、 程式輸入字典和程式輸出字典。這些成果 根字典。
元件輸入字典是包含所有功能的字典
按父項 offer
到元件;也就是所有功能
元件可轉送 from parent
的流量
元件輸出字典是包含所有功能的字典
將元件 expose
套用至其父項;也就是所有需要
父項可以轉送 from #component
。
程式輸入字典是包含所有功能的字典
透過元件 use
程式輸出字典是包含元件所有
capability
宣告。
我們可根據下列定義來表達能力轉送作業:
use
、offer
、expose
和capabilities
是轉送作業, 轉送字典之間的功能。use
將能力從根字典轉送至程式輸入 字典。expose
會將能力從根字典轉送至元件 輸出字典。offer
會將能力從根字典轉送至子項的 。capabilities
會在程式輸出字典中提供能力 可供轉送
透過這項設計,我們將一般化,讓轉送作業能夠 將任意字典當做來源,而不僅是根:
use
將能力從字典轉送至程式輸入 字典。expose
將能力從字典轉送至元件輸出 字典。offer
將能力從字典轉送至子項元件 輸入字典 或其他字典。
宣告
如何定義全新的空白字典:
capabilities: [
{
dictionary: "diagnostics-bundle",
},
],
如要定義會沿用現有字典內容的字典,
透過 extends
提供該字典的路徑 (請參閱
擴充功能):
{
dictionary: "diagnostics-bundle",
extends: "parent/logging-bundle/sys",
},
匯總
如要將能力匯總至字典中,請將功能轉送至字典中,
offer
中的 to
關鍵字。由於字典是由
元件,其包含該元件的根字典為 self
。相同的關鍵字
都支援一般 offer
。舉例來說,您可以將
使用 as
關鍵字,在目標字典中加入能力的名稱。
capabilities: [
{
dictionary: "diagnostics-bundle",
},
],
offer: [
{
protocol: "fuchsia.logger.LogSink",
from: "#archivist",
to: "self/diagnostics-bundle",
},
{
protocol: "fuchsia.inspect.InspectSink",
from: "#archivist",
to: "self/diagnostics-bundle",
},
{
directory: "publisher",
from: "#debugdata",
to: "self/diagnostics-bundle",
rights: [ "r*" ],
as: "coverage",
},
],
委派
委派代表轉送字典:
offer: [
{
dictionary: "diagnostics-bundle",
from: "parent",
to: "#session",
},
],
與其他能力路徑一樣,您可以使用
as
關鍵字。
offer: [
{
dictionary: "logging-bundle",
from: "parent",
to: "#session",
as: "diagnostics-bundle",
},
],
對等的執行階段 API 將 動態優惠。
建立巢狀結構
字典可以透過轉送到其他字典,以包含其他字典 使用 aggregate 語法建立另一個字典:
capabilities: [
{
dictionary: "session-bundle",
},
],
offer: [
{
dictionary: "driver-services-bundle",
from: "parent",
to: "self/session-bundle",
},
],
擷取
按照正式程序進行,我們會擴充 from
關鍵字,不僅只接受根字典,也是以巢狀結構形式
根層級字典
如要從字典中擷取能力,請在 from
中為字典命名。這個
字典相對於根字典 (parent
、#child
等)
offer: [
{
protocol: "fuchsia.ui.composition.Flatland",
from: "parent/session-bundle",
to: "#window_manager",
},
],
這個方法也適用於 use
:
use: [
{
protocol: "fuchsia.ui.composition.Flatland",
from: "parent/session-bundle",
},
],
如果字典會嵌入其他字典中,也可以使用擷取功能:
use: [
{
protocol: "fuchsia.ui.composition.Flatland",
from: "parent/session-bundle/gfx",
},
],
擴充功能
在字典定義中使用 extends
選項,從另一個資料夾繼承
字典:
capabilities: [
{
dictionary: "session-bundle",
// `session-bundle` is initialized with the dictionary the parent
// offered to this component, also called `session-bundle`.
extends: "parent/session-bundle",
},
],
offer: [
{
dictionary: "session-bundle",
from: "self",
to: "#session-manager",
},
{
protocol: "fuchsia.ui.composition.Flatland",
from: "#ui",
to: "self/session-bundle",
},
],
可變動性
以宣告方式建構的字典無法變更,因此非常實用 security 屬性。才能修改字典 就必須在 runtime 中建立。
字典中功能的中繼資料
將功能放入字典中時,他們會保留所有類型 和中繼資料,這兩者與 如字典本身
例如,如果能力具有 optional
可用性,就屬於這種情況。
會由元件 A
新增至字典,而 B
元件會擷取
能力,在擷取時將有 optional
可用性
即使字典本身的可用性為 required
。
我們可能會在匯總時對可用性施加某些限制。
舉例來說,禁止將 required
能力放入
optional
字典,因為這屬於一般的不變體,
從目標轉送到來源時,可用性一律不會降低。
執行階段與宣告式字典之間的互通性
在執行階段建立的字典必須與以下項目的字典互通: 元件宣告如果不是的話,就會強制使用者進入 只選擇其中一種,因為這樣才能證明 然而,組合的基礎不足以解決這兩種使用情境 以類似的方式展示
互通性的設計細節將做為後續追蹤 提案。
這項功能的主要已知用途是轉送的驅動程式庫架構 已填入執行階段的 Service Bundle。
實作
Cml 中的到達網頁字典會遵循一般管道來導入
Cml 功能首先,在 cml 和 component.decl 中新增字典
結構定義。接著,我們會更新 cmc
、cm_fidl_validator
、cm_rust
,以及
realm_builder
用於編譯、驗證及代表字典。堅持將
這個外掛程式也能更新辨識字典
字典路徑
系統已在處理相關工作,以將字典 (做為信任類型) 整合至 和轉送引擎字典 API 的實作 應根據這項工作建立字典,將這些字典做為後端 以及用於轉送字典功能的傳輸工具。
成效
沒有任何特殊的效能注意事項。轉送字典應為 就能更快或更快 個別。
人體工學
改善建築物元件拓撲的人體工學是 這項設計。
導入新功能會自然提高 API 的複雜度 我們相信這不只是因為日益降低的複雜性, 透過在拓撲中納入字典
回溯相容性
但 cmc 尚未針對元件資訊清單功能提供版本管理支援,因此
必須注意,避免與預建資訊清單的相容性問題發生。
幸好,為字典引進的所有新語法都能與
所以也能更輕鬆執行工作例如:目前的名稱
from
的語法成為新路徑語法的特殊案例。
如果能力路徑的一部分通過字典,則任何安全性政策 所有相關的能力仍須適用。
安全性考量
在字典中轉送功能時,會失去部分透明度,因為 字典中功能的身分的身分會隱藏 路徑中的中繼元件不過,他們仍可透過 沿著路線向供應商查詢。這是故意的行為 以實現字典的彈性和功能。
宣告式建立的字典無法變更。針對這些字典 可以執行 進行深度優先搜尋,從目標到 。
如果在字典替換環境時,這項功能會強化安全性 系統的防護機制與環境不同 方法與其他功能相同
隱私權注意事項
此提案對隱私權沒有任何影響。
測試
我們會像多數元件管理員功能一樣進行測試,在
component_manager
和 cmc
,以及
component_manager/tests
。我們也會加入整合測試,以便檢查
會對含有字典的路徑套用練習字典和政策。
說明文件
我們會更新 //tools/lib/cml
中的 rustdoc。
新增頁面至 //docs/concepts/components
說明字典。
新增範例至 //examples/components
。
缺點、替代方案和未知
替代方法 1:字典中的「in
」和「into
」關鍵字
宣告
「字典功能」是一種會授予 cml/component.decl 能力類型 字典的存取權限。
宣告字典的方式與其他元件架構能力相同。是兩個
字典建立方式的變化版本,取決於是否有 extends
字詞。
首先,您可以定義全新的空白字典:
capabilities: [
{
dictionary: "diagnostics-bundle",
},
],
或者,您也可以定義字典,其內容會沿用現有
方法是在 extends
中指定字典路徑和
from
(請參閱擴充功能):
{
dictionary: "diagnostics-bundle",
extends: "logging-bundle/sys",
from: "parent",
},
匯總
如要將能力匯總至字典中,請使用
into
關鍵字:
capabilities: [
{
dictionary: "diagnostics-bundle",
},
],
offer: [
{
protocol: "fuchsia.logger.LogSink",
from: "#archivist",
into: "diagnostics-bundle",
},
{
protocol: "fuchsia.inspect.InspectSink",
from: "#archivist",
into: "diagnostics-bundle",
},
{
protocol: "fuchsia.debugdata.Publisher",
from: "#debugdata",
into: "diagnostics-bundle",
},
],
委派
與主要設計相同。
建立巢狀結構
只要將字典轉送到其他字典,即可包含這些字典 轉換為字典:
capabilities: [
{
dictionary: "session-bundle",
},
],
offer: [
{
dictionary: "driver-services-bundle",
from: "parent",
into: "session-bundle",
},
],
擷取
我們引進新的 in
關鍵字,以指定字典以擷取
所有文字
當 in
存在時,能力關鍵字 (protocol
等) 指的是
能力,而不是由工作人員直接提供的能力
「from
」中命名的元件
in
可以是名稱或路徑 (名稱可以視為去產生大小寫形式)。如果
這個名稱,指的是 from
顯示的字典。如果是路徑,
路徑的第一個區段會指定由 from
提供的字典,而
路徑的其餘部分會指定連至在此字典中的字典路徑。
use
、offer
、expose
支援 in
。內容一律為選填欄位。
offer: [
{
protocol: "fuchsia.ui.composition.Flatland",
from: "parent",
in: "session-bundle/gfx",
to: "#window_manager",
},
],
expose: [
{
protocol: "fuchsia.ui.composition.Flatland",
from: "#scenic",
in: "gfx-bundle",
},
],
use: [
{
protocol: "fuchsia.ui.composition.Flatland",
in: "session-bundle/gfx",
},
],
擴充功能
在字典定義中使用 extends
關鍵字,從另一個資料夾繼承
字典:
capabilities: [
{
dictionary: "diagnostics-bundle",
extends: "parent/logging-bundle/sys",
},
],
offer: [
{
dictionary: "diagnostics-bundle",
from: "self",
to: "#session-manager",
},
{
protocol: "fuchsia.tracing.provider.Registry",
from: "#trace_manager",
into: "diagnostics-bundle",
},
],
替代方法 2:能力 ID 中的路徑
您不必在 from
中指定字典的路徑,路徑可能會是
部分能力 ID 的一部分 (protocol
、directory
等)
匯總
與主要設計相同。
委派
與主要設計相同。
建立巢狀結構
與主要設計相同。
擷取
如要從字典中擷取能力,請指定能力的路徑
在能力 ID 的字典中 (protocol
、directory
、
等)。
offer: [
{
protocol: "session-bundle/fuchsia.ui.composition.Flatland",
from: "parent",
to: "#window_manager",
},
],
目標中的名稱會預設為最後一個路徑元素或「dirname」。
(fuchsia.ui.composition.Flatland
)。或者,您也可以使用 as
重新命名:
offer: [
{
protocol: "session-bundle/fuchsia.ui.composition.Flatland",
from: "parent",
to: "#window_manager",
as: "fuchsia.ui.composition.Flatland-windows",
},
],
這也適用於 use
,其可提供字典中的能力
加入計畫與其他 use
宣告一樣,預設目標路徑
在 /svc
上重新基準名稱 (最後一個路徑元素):
use: [
{
protocol: "session-bundle/fuchsia.ui.composition.Flatland",
path: "/svc/fuchsia.ui.composition.Flatland", // default
},
],
路徑語法也適用於其他字典中的字典:
use: [
{ protocol: "session-bundle/gfx/fuchsia.ui.composition.Flatland" },
],
擴充功能
在字典定義中使用 origin: #...
選項,從另一個資料夾繼承
字典:
capabilities: [
{
dictionary: "session-bundle",
// Source of the dictionary to extend (in this case, the one named
// "session-bundle" from the parent)
origin: "#session",
from: "parent",
},
],
offer: [
{
dictionary: "session-bundle",
from: "self",
to: "#session-manager",
},
{
protocol: "fuchsia.ui.composition.Flatland",
from: "#ui",
into: "session-bundle",
},
],
替代方法 3:功能 ID 成為路徑
名稱 ->路徑
確切來說,cml 中的能力 ID 是名稱,這類 ID 沒有本質上 巢狀結構結構例如:
offer: [
{
protocol: "fuchsia.fonts.Provider",
from: "#font_provider",
to: "#session-manager",
},
],
但功能 ID 確實能對應至 capabilities
中的路徑
和 use
區段以通訊協定來說,這通常屬於隱含的:
則 cmc 會填入 /svc/${capability-name}
的預設路徑。例如:
use: [
{
protocol: "fuchsia.fonts.Provider",
// path in namespace
path: "/svc/fuchsia.fonts.Provider",
},
],
capabilities: [
{
protocol: "fuchsia.fonts.Provider",
// path in outgoing directory
path: "/svc/fuchsia.fonts.Provider",
},
],
這個替代方案會能力中的路徑。更正式:
- 功能 ID 是一或多個名稱
字元集
[A-Za-z0-9_-.]
,包含 1 至 100 個半形字元,並以半形逗號分隔 由/
個字元組成。不允許開頭是/
。- 或規則運算式語法:
[A-Za-z0-9_-]{1,100}(/[A-Za-z0-9_-]{1,100})*
- 現有的能力 ID 與新的 語法。
- 或規則運算式語法:
下文將說明這個語法如何自然奠定組合的基礎。
匯總
如要將功能匯總成字典,請以相同路徑轉送這些功能 前置字串:
offer: [
{
protocol: "fuchsia.logger.LogSink",
from: "#archivist",
to: "all",
as: "diagnostics/fuchsia.logger.LogSink",
},
{
protocol: "fuchsia.inspect.InspectSink",
from: "#archivist",
to: "all",
as: "diagnostics/fuchsia.inspect.InspectSink",
},
{
protocol: "fuchsia.debugdata.Publisher",
from: "#debugdata",
to: "all",
as: "diagnostics/fuchsia.debugdata.Publisher",
},
],
委派
委派功能只會按照以下方式轉送字典:
offer: [
{
dictionary: "diagnostics",
from: "parent",
to: "#session",
},
],
建立巢狀結構
您可以透過建立巢狀結構的 字典的路徑前置字串:
offer: [
{
dictionary: "driver-services-bundle",
from: "parent",
to: "#session-manager",
as: "session/driver-services",
},
],
擷取
您只需在您要擷取的字典中命名能力即可:
offer: [
{
protocol: "session-bundle/fuchsia.ui.composition.Flatland",
from: "parent",
to: "#window_manager",
as: "fuchsia.ui.composition.Flatland",
},
],
這個方法也適用於 use
:
use: [
{
protocol: "session-bundle/fuchsia.ui.composition.Flatland",
path: "/svc/fuchsia.ui.composition.Flatland",
},
],
如果字典嵌入其他字典中 (TODO: 範例)
擴充功能
重新命名功能,使其路徑前置字串與字典一致:
offer: [
{
protocol: "session-bundle",
from: "parent",
to: "#session-manager",
},
{
protocol: "fuchsia.ui.composition.Flatland",
as: "session-bundle/fuchsia.ui.composition.Flatland",
from: "#ui",
to: "#session-manager",
},
],
為什麼要使用字典而非目錄?
與其導入字典,不如使用 fuchsia.io
目錄做為
套裝組合的基本類型。從一個層面來說,這是一種吸引人:目錄
並提供專屬的階層架構。不過
有許多關於使用目錄的引數:
- VFS 型別系統提供的資訊與 CF 類型系統不同。 例如服務、目錄和儲存空間 VFS 中的子目錄,即使在 CF 中屬於不同類型也是如此。
- 目錄的介面比 所需的基礎架構功能包括 NODE_REFERENCE、連結 旗標、屬性、資料檔案等項目與合併用途無關。
- VFS 程式庫的大小對某些應用程式而言太大,尤其是
驅動程式。因此
共享中有
//sdk/lib/component/outgoing
個相片庫連結 程式庫輔助程式 (//sdk/lib/svc
),而非 VFS 程式庫 但須犧牲功能和透明度 - 這沒有一種 VFS 實作,但有兩個獨立的 C++ 實作 以及一個 Rust 實作項目這些實作方式有些微差異 以及功能有落差這並不是字典問題,因為字典中 單一字典實作。
- 目錄會增加編寫程式碼生成繫結的難度 表示程式以獨立方式提供或消耗的各項能力 語言元素。
- 目錄自然不支援「匯總」或「擴充功能」 作業。必須藉由提供新目錄來模擬,而且其中有些 節點會重新導向至舊節點,這既容易實作又容易 。
日後的工作
針對驅動程式庫程式的用途,我們會單獨提出隨附設計建議。 僅憑本提案中的功能,無法完全解決這些問題。
這項設計開啟了更加經濟能力轉送的語法語法。
而不是能力名稱與 from
各自獨立的屬性
可以合併成單一路徑,在概念上,這個路徑就稱為字典
當中包含所有根字典例如:
offer: [
{
protocol: "#ui/fuchsia.ui.composition.Flatland",
to: "#session-manager",
},
],
這個語法有個好屬性:它會自然而然地使用一般化原則 轉送整個根字典:
offer: [
{
// Plumb all capabilities from parent to child #session-manager
dictionary: "parent",
to: "#session-manager",
},
],
另外還有一個通用版本,將語法統一 更多:
route: [
{
// Path to source capability in dictionary
src: "#ui/fuchsia.ui.composition.Flatland",
// Path of target capability in dictionary
dst: "#session-manager/fuchsia.ui.composition.Flatland",
},
],
route: [
{
src: "parent",
dst: "#session-manager/parent",
},
],
既有藝術品和參考資料
功能組合已經舊的概念。有很多內部前文文件 提出類似概念的提案