RFC-0083:FIDL 版本管理 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 提供方法為特定版本建立 FIDL 元素版本及產生繫結。 |
問題 | |
毛皮變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-02-12 |
審查日期 (年-月-日) | 2021-04-05 |
摘要
本文件提議以版本和 機制能針對特定版本產生繫結這會將 API 演進化 如此一來,圖書館作者就能更輕鬆地變更 以穩定的方式提供給終端開發人員這奠定了 FIDL 角色的基礎 RFC-0002:平台版本管理中。
提振精神
雖然 FIDL 在變更期間針對 ABI 相容性提供許多預設用途, 難以持續改良 API在 Fuchsia SDK 中進行 FIDL 變更 與 ABI 相容但與 API 不相容時,需要經過審慎協調 柔和轉換,以免破壞下游編譯。發生問題時 這時通常就必須回復 Fuchsia 的變更。使用 SDK 時 程式庫會不斷增加,導致這些變更困難。
FIDL 版本管理解決了這個問題,讓 FIDL 程式庫作者和使用者 向前邁進程式庫作者新增、移除或修改時 或 API,變更會在新的 API 級別中發布。指定 舊版 API 級別在採用新的 API 級別前,繫結不會有任何變更。 除了提供穩定性外,開發人員也能改用新的 API 因為每個元件要指定目標 API 級別,因此每次只能處理一個元件。
圖 1 說明瞭破壞的 API 變更。如未設定版本管理 會導致應用程式中斷並連至還原啟用版本管理功能後 只是固定在舊的 API 級別當然,同樣的問題 當嘗試將應用程式固定的 API 級別從 12 提升至 13 時,就會發生這個情況。 但只要以非同步方式修正,就不必還原 Fuchsia 並磨練這項專案,
圖 1:API 演變 (左側) 和之後 (右側) FIDL 版本管理之前
術語
API 級別和 ABI 修訂版本等詞彙定義於 RFC-0002: Platform 版本管理,變更如下:
RFC-0002 修訂條款。Fuchsia API 級別為 63 位元未簽署的 API 級別 整數值。換句話說,它為 64 位元,但高位元必須為零。
FIDL 元素是 FIDL 程式庫的獨立部分,會影響產生的 繫結。具體措施包括:
- FIDL 程式庫本身
- 常數、列舉、位元、結構體、資料表、聯集、通訊協定和服務宣告
- 別名和新類型 (擷取自 RFC-0052:類型別名和新類型)
- 列舉、位元、結構體、資料表、聯集和服務 (包括
reserved
名資料表和聯集成員) - 通訊協定中的方法和
compose
個段落 - 方法中的要求和回應參數
FIDL 屬性是 FIDL 元素的可修改部分,本身並非 不同元素具體措施包括:
- 屬性
strict
、flexible
和resource
修飾符- 常數、列舉成員和位元成員的值
- 結構體成員的預設值
- 類型限制 (成員、參數和類型別名)
- 方法種類 (單向、雙向、事件)
- 方法錯誤語法 (狀態和類型)
這只會留下幾個不是 FIDL 元素或屬性的項目:
- 個別
.fidl
檔案 - 其他 FIDL 程式庫的匯入項目
- 僅限 FIDL 的
using
別名,RFC-0052 會從語言中移除 - 實驗性
resource_definition
宣告 - 註解,包括說明文件註解
設計
本文件所述的設計是一般用途 FIDL 元素的版本管理其主要用途是將 FIDL 程式庫 建立每個 API 級別的 Fuchsia Platform
範圍
此設計引入了 FIDL 語言的版本管理概念, 轉換成 FIDL 程式庫能指定 Pod 的語法和語意 版本管理屬性,包括它們與 FIDL 其他層面的互動方式 例如父項-子項和「定義關係」可定義 會在產生 FIDL 繫結時做為輸入內容提供。
這項設計「不會」建議 FIDL 的套件管理員。主題: 版本解析演算法、套件發布版本和依附元件衝突 超出範圍儘管如此,解決這些問題的系統應該 讓使用者能夠重複使用這項設計提供的工具
本提案並著重在 API,而非 ABI。 因此,通訊協定演進的主題超出範圍。這包括 並提問,例如「FIDL 伺服器如何支援多個 ABI 修訂版本?」有 都是 FIDL 和元件管理服務 日後就會採用本提案為通訊協定的演變奠定了基礎 我們在 FIDL 中導入版本概念,但重點不止於此。
在這項設計中代表轉場效果的能力對於 無論轉換是否安全或相容相較之下,版本化的 FIDL 程式庫可以代表絕大多數的語法有效變更。
正式主義
「平台 ID」是為版本提供背景資訊的標籤。平台
ID 必須是有效的 FIDL 程式庫名稱元素,即本文撰寫時的做法
符合規則運算式 [a-z][a-z0-9_]*
。
版本 ID 是介於 1 到 2^63-1 之間的無正負號 64 位元整數
(含) 或等於 2^64-1。後者的版本 ID 稱為 HEAD
而且會經過特別處理
修訂條款 (2022 年 10 月)。為支援舊版方法,我們會改用
HEAD
為 2^64-2,LEGACY
則為 2^64-1。
修訂條款 (2024 年 4 月)。已在 RFC-0246 中重新定義
HEAD
和LEGACY
。
版本 ID 完全依照「is 大於」屬性排序關係 版本 X 在 X > 時比 Y 版來得新。
與平台相關的 FIDL 元素的供應情形是指 元素導入時的版本,並視需要顯示版本 而是已淘汰,且已移除。淘汰和移除必須晚於 簡介1。如果兩者已提供,移除必須早於淘汰日期。
FIDL 元素是版本管理的平台版本 (如果擁有 各方獲得多少評分如果是在任何平台下的版本,則為「版本化」。
平台版本對應的 FIDL 元素可使用 晚於或等於該元素的簡介,但早於該元素的簡介 淘汰和移除 (如有)如果該版本較新,就會已淘汰。 等於或等於該元素已淘汰,但早於移除時間 (如有)。 在適用或已淘汰的情況下,「顯示」了。否則就「不存在」。
「版本選擇」是將版本指派給一組平台。適用對象
舉例來說,您可以選取 red
的第 2 版,以及 blue
的 HEAD
版。
FIDL 元素可使用,適用於版本選擇項目 (如有) 適用於各種平台如果有,就會淘汰 不適用於所有平台,但不適用於一或多個 平台。否則就「不存在」。
語法
供應情形屬性的格式為 2,其靈感來自 Swift 的
available
屬性:
@available(added=<V>, deprecated=<V>, removed=<V>)
每個 <V>
都是版本 ID。《added
》、《deprecated
》和《removed
》
] 欄位會指出元素簡介、淘汰及移除
。這些都是選填項目,但必須提供至少一個項目。
在程式庫中,必須提供 added
欄位 (deprecated
和 removed
為
選用)。此外還有一個選用欄位 platform
,用於指定平台
或 ID。程式庫中的所有版本 ID 都是指
平台。例如:
@available(platform="red", added=2)
library colors.red.auth;
省略時,預設為程式庫名稱的第一個元件:
@available(added=HEAD) // implies platform="blue"
library blue.auth;
使用 deprecated
欄位時,可額外提供額外的 note
欄位
列在警告訊息中例如:
@available(added=12, deprecated=34, note="Use X instead")
供應情形屬性構成 RFC-0058 中的 [Deprecated]
屬性:
加入過時的 [Deprecated]
屬性。
版本管理元素
FIDL 元素是以供應情形屬性建立版本。每個 FIDL 元素 最多只能有一個供應情形屬性,而且只能透過版本管理 程式庫換句話說,如果程式庫中有任何 FIDL 元素已加註, 必須一併為程式庫加上註解
FIDL 程式庫中的每個檔案都有自己的程式庫宣告,但所有檔案 代表同一個 FIDL 元素:程式庫。這與 FIDL 一致 風格指南:
將程式庫分割為多個檔案,對 程式庫。...將程式庫分割成多個檔案,以盡量提升可讀性。
因此,一個程式庫中只有一個程式庫宣告可以有一個可用性。 屬性。文件註解的限制都相同,因此最好 選擇相同的檔案來指定程式庫可用性及其文件註解。
版本管理屬性
您無法直接建立 FIDL 屬性的版本。如要變更資源,你必須 swap 元素。複製元素 新舊版本的推出。舉例來說 請變更以第 12 版繫結的字串:
@available(removed=12)
string:50 info;
@available(added=12)
string:100 info;
或者,將列舉從 strict
變更為 flexible
:
@available(removed=12)
strict enum Color { ... };
@available(added=12)
flexible enum Color { ... };
除了程式庫之外,所有 FIDL 元素都可以替換。不會發生名稱衝突 因為供應範圍不會重疊
本提案未涵蓋日後套用供應情形的語法
屬性直接寫入 FIDL 屬性如果導入這類語法,
僅支援 added
和 removed
,因為沒有以下項目的解讀:
在所有 FIDL 屬性中通用的 deprecated
。
繼承
FIDL 元素形成有向非循環圖,子元素沿用了 以及父項元素的可用性
頂層宣告繼承自程式庫,列舉、位元、
結構體、資料表、聯集和服務繼承了封閉宣告。
要求/回應參數繼承自其方法。方法和 compose
字節從封閉通訊協定繼承Compose 的方法繼承自
原始方法和 compose
音節。不使用通訊協定組合時
圖表為樹狀圖
如果子元素具有供應情形屬性,則會覆寫沿用的子元素 提高可用性這種做法不得為重複或牴觸: 簡介版本只能更新、淘汰及移除 版本只能設為較舊
在組合方法中,如果兩個父項都在同一個平台底下建立版本,
其可用性即為其父項交互作用的播映資訊 (最新)
以及最舊的淘汰和最舊的移除)。是否有版本管理
該組合方法會沿用兩個
播映情形。在此情況下,定義中的「可用
而非「選擇版本」與其產生關聯在這兩種情況下
note
來自兩個上層發布商。
以下是平台內組合的常見情況:
library foo;
protocol Def { @available(added=A, deprecated=B, removed=C) Go(); };
protocol Use { @available(added=D, deprecated=E, removed=F) compose Def; };
原始方法 foo/Def.Go
是在 A
導入、已於 B
淘汰,且
已於 C
移除組合方法 foo/Use.Go
會在 max(A,D)
導入。
已於 min(B,E)
淘汰,並在 min(C,F)
移除。也就是說
方法受 compose
節的可用性限制,但有些方法可
如果 Def
在 compose
導入後導入這些素材資源,可用性會縮小範圍。
或在 compose
淘汰/移除前,淘汰/移除這些素材資源
使用驗證功能
某些 FIDL 元素在各元素間「使用」另一個相關。A 罩杯 struct/table/union 或 request/response 參數會在下列情況使用 FIDL 元素: 元素出現在元素中方法 (如果元素發生錯誤時) 類型;const 或列舉/位元成員 (如果元素出現在元素值中);結構體 成員。以下列舉部分範例:
const uint32 X = 10;
const uint32 Y = X; // Y uses X
table Entry {};
protocol Device {};
resource struct Info {
vector<Entry>:X entries; // entries uses Entry and X
request<Device> req; // req uses Device
uint32 val = Y; // val uses Y
Info? next; // next uses Info
};
如果有選擇版本,Fidlc 會在下列情況產生錯誤:
- 目前元素使用不存在的元素。或
- 可用的元素使用了已淘汰的元素。
生命週期語意
如果選擇版本,如果有 FIDL 元素,會以下列形式發出
正常工作。如果已遭淘汰,我們會在 JSON IR 中表示,
繫結行為如「RFC-0058:導入 [Deprecated]
」一文所述
屬性:如果沒有,我們會從 JSON IR 中省略該欄位。
如有任何 FIDL 元素未獲「使用」,請加上註解
@available(removed=<N>)
等同於從 .fidl
刪除
檔案,不過使用 removed
屬性可維持歷來準確率。
刪除元素則不會這種做法可避免 .fidl
隨著資料量變化而變得毀損且無法讀取。
HEAD
的用途
HEAD
版本 ID 代表開發的出血邊緣。
用戶端可以自由針對 HEAD
繫結編寫程式,但這不應預期
您必須要能穩定運作舉例來說,假設您下載了 red.fidl
,其中
註解中使用的最高版本 ID 為 12 和 HEAD
。如果發生以下情況:
下載較新的 red.fidl
副本,但您仍可透過
版本 12 完全相同,亦即作者尚未修改紀錄。但
HEAD
API 可能會完全不同。
這項功能可在採用 FIDL 版本管理時沿用。如要依賴
版本化程式庫的 HEAD
繫結與根據繫結而定
最基本的程式庫
還能讓協作專案更輕鬆地變更 FIDL。編寫
CL,查詢目前版本非常繁瑣且容易上手,尤其是尤其是
並做出變更協作者可以直接使用 HEAD
,且
專案擁有者之後可以將其替換為特定版本。
舊版支援
修訂條款 (2022 年 10 月)。這是在接受 RFC 後加入的。
使用 @available(removed=<N>)
移除 API 後,該 API 就不會再出現在
為版本 N 以上版本產生的繫結。因此很難建構
支援多個 API 級別的 Fuchsia 系統映像檔。如果系統映像檔
針對 N-1 繫結建立而成,但無法提供方法的實作
已在 N 新增。如果是針對「N」繫結建立而成,則無法提供
在 N 中移除方法的實作。
為解決這個問題,我們推出了名為 LEGACY
的新版本,用來
與 HEAD
相同,但也包含舊版方法「舊版方法」是一種方法
標示為@available(removed=<N>, legacy=true)
。這會使用新的布林值引數
名為 legacy
的預設值為 false,且只有在 removed
為
。例如:
@available(added=1)
library example;
protocol Foo {
@available(removed=2) // implies legacy=false
NotLegacy();
@available(removed=2, legacy=true)
Legacy();
};
以下是該範例繫結中包含的方法,用於指定 不同版本
目標版本 | 包含的方法 |
---|---|
1 | NotLegacy 、Legacy |
2 | |
HEAD |
|
LEGACY |
Legacy |
根據政策,Fchsia 平台中的所有方法都應保留
提供支援。Fuchsia 平台停止支援
您可以放心移除 legacy=true
和
方法的實作內容。
當 Fuchsia 平台做為用戶端 (而非伺服器) 時,傳統方法
讓平台繼續針對那些指定舊的 API 呼叫方法
級別。對於那些不預期的情況
必須標示為 flexible
,以便忽略呼叫。請參閱 RFC-0138:
處理不明互動的詳細資訊。
legacy
引數可用於任何 FIDL 元素,不限於方法。適用對象
舉例來說,如果您同時移除類型以及使用該類型的方法,
類型也必須標示為 legacy=true
。這只是使用
驗證,而非新規則。
再舉一個例子,要求使用的資料表。移除其中一個
欄位,建議您使用 legacy=true
,讓伺服器能繼續
也就是負責設定欄位的另一方面,如果忽略欄位
足以保留 ABI,無需舊版支援。同樣地
,只有在符合以下情況時使用 legacy=true
如為保留 ABI 用於保留 ABI,則移除欄位時
用戶端。
請注意,更換 元素,因為播映資訊代表變更,而非移除。如果您之前要 否則會導致錯誤:
protocol Foo {
@available(removed=2, legacy=true)
Bar();
@available(added=2)
Bar();
}
由於第一個 Bar
會在 LEGACY
加回,而第二個 Bar
永遠不會
已移除,它們都位於 LEGACY
和 fidlc 都會發出類似錯誤
但對於播映資訊重疊的相同名稱元素
其實不會有太大影響
JSON IR
為了在 IR 中表示淘汰,我們新增了兩個欄位:
deprecated: <bool>, // required
deprecation_note: <string>, // optional
這些指令已新增至下列 JSON IR 結構定義定義:
#/definitions/bits
#/definitions/bits-member
#/definitions/const
#/definitions/enum
#/definitions/enum-member
#/definitions/interface
#/definitions/interface-method
#/definitions/service
#/definitions/service-member
#/definitions/struct
#/definitions/struct-member
#/definitions/table
#/definitions/table-member
#/definitions/union
#/definitions/union-member
#/definitions/type_alias
請注意,IR 並不代表程式庫的淘汰情形。仍具有 透過繼承造成的效果,以及下一節所述的警告。
指令列介面
如要指定版本,fidlc 會接受 --available <P>:<V>
,其中
<P>
是平台 ID,<V>
是版本 ID。這個標記可以
可以多次提供不同的平台 ID例如:
fidlc --json out.json --available red:2 --available blue:HEAD
--files red.fidl --files blue.fidl
如果所選版本缺少平台或平台未使用 (與指定程式庫版本相比的平台),fidlc 就會產生錯誤如果與 版本選取,Fidlc 會產生警告/錯誤。3
政策
FIDL 版本管理功能可讓您在不造成應用程式破壞的情況下進化 API。 但這不能保證為此,我們採用下列政策 特別是 Fuchsia 平台:
- 將發生在
HEAD
的所有新變更加上註解。 - 請勿變更 FIDL 程式庫的歷史記錄。唯一的例外狀況是程序 請參閱下文所述的刪除舊 FIDL 元素。
- 先淘汰 FIDL 元素再移除,但 來變更屬性。
- 淘汰元素時:
- 請使用
note
欄位告訴開發人員要改用什麼內容。 - 在文件註解中撰寫
# Deprecation
部分,提供更詳細的資訊 說明及公布淘汰時程
- 請使用
- 變更 FIDL 屬性時請務必謹慎。適用對象 例如將類型從嚴格改為彈性,或 從值到資源,可能具有重大 API 這種做法API 委員會應逐案判斷這些異動。
這些政策的實施方式如下:
- 對於 SDK 中的所有 FIDL 變更,仍須通過 API 委員會核准。
fidl-lint
應檢查已淘汰的元素是否設有note
欄位 以及文件註解中的# Deprecation
部分。- 日後應該會執行 CQ 工作來強制執行其他政策 (變更記錄、在移除前淘汰,以及 API/ABI 不相容) (變更) 物件類別。
另外還有兩個新程序,其詳細資料會延遲至較晚的 RFC:
- 推出新的 API 級別。系統可能會按固定的時間表進行這項作業,
自上次 API 級別以來所做的部分或所有變更,都會在新的
以新層級取代
HEAD
的例項,藉此達到 API 級別。 - 刪除舊的 FIDL 元素。經過一段時間之後,標示為
您可以從
.fidl
個檔案中刪除。如要刪除元素, 資源並未參照任何位置,因此這項程序可能需要刪除 按照固定時程,列出超過特定 API 級別的所有元素。
我們可以利用相同樹狀結構建立工具 來簡化這兩個程序 套用訪客策略
實作
這項設計大多可透過 fidlc 實作。剖析 @available
語法
依賴其他 RFC,變更 FIDL 的註解語法。
語意可能會在實驗性標記之後導入,
當 fidlc 編譯程式庫時 (即使它會為單一資料產生 JSON IR) 版本,應同時驗證所有可用版本。它應該 並依序產生及檢查每個版本。相反地 是否應暫時將元素分解為 (名稱、版本範圍) 元組。這個 程序與將 NFA 轉換為 DFA 類似。例如:
type MyTable = table {
@available(added=2)
1: name string;
@available(added=HEAD)
2: age uint32;
};
這項操作將按以下方式分解 (使用虛擬語法示範):
type «MyTable, [0,1]» = table {};
type «MyTable, [2,HEAD)» = table { 1: name «string, [0,HEAD]»; }
type «MyTable, HEAD» = table { 1: name «string, [0,HEAD]»; 2: age «uint32, [0,HEAD]» };
在發出 IR 之前,fidlc 會縮減宣告內容,使其只包含 。
開啟問題。時間分解方法難以一般化 多個平台版本化的 FIDL 程式庫組合在一起 因為我們的主要用途 (版本管理 Fuchsia 版本) 不需要用到此方法 「Platform by API level」(依 API 級別區分) 類別) 則會延後這個問題,並在一開始就有專案 ID 僅允許一個
--available
標記。
HEAD
版本 ID 可以做為內容專屬常數來實作。
與允許做為長度的 MAX
常數類似
對字串和向量的限制
另外,對於 fidlc 外也有一些實作作業。首先,Fidldoc 必須
也要考量版本管理舉例來說,如果元素已不適用,
說明文件,應清楚指出這一點。也可以提供
下拉式選單,以查看歷史文件。第二是 FireEye 後端
必須使用 JSON IR 中的 "deprecated"
欄位。例如 fidlgen_rust
可轉譯為 #[deprecated]
Rust 屬性請參閱 RFC-0058:
推出 [Deprecated]
屬性,以提供其他語言的範例。
在 SDK 中的程式庫開始使用註解之前,我們必須
--available fuchsia:HEAD
至 GN 範本,用於建構 FIDL 繫結。這個
假設所有樹狀結構內程式碼都使用 HEAD
繫結。時間
我們對 C++ 提供了平台版本管理提案
與其他版本的 FIDL 繫結相互比對,以進行測試。
在寵物建構系統中,我們將新增 fuchsia_api_level
宣告和線路
更新為 --available
旗標這會需要與 fidlc 協調相關事宜
CLI 變更:先接受並忽略
--available
旗標,再要求使用。
成效
此提案不會影響執行階段效能。會影響建構效能 在 fidlc 必須執行更多作業的程度,但 FIDL 編譯從未如此 是 Fuchsia 建構時間的重要因素
安全性考量
此提案將對安全性產生正面影響,因為版本管理 可以更輕鬆地遷移至具有更高安全性屬性的新 FIDL API。這個 是否應高於增加攻擊面所帶來的負面影響。 可支援舊版 ABI 修訂版本
本提案並未提供隱藏 ABI 的機制, 應用程式的目標 ABI 修訂版本, RFC-0002。雖然這可以提高安全性 經過改良的設計是全方位的 RFC 演變過程的一部分。
隱私權注意事項
此提案將對隱私權產生正面影響,因為版本管理 遷移至新的 FIDL API 及隱私權屬性更完善
測試
我們目前使用單元測試和黃金的組合來測試 FIDL 工具鍊
測試。單元測試主要用於 fidlc 內部。金級測試計畫:
編譯一組 .fidl
檔案,並確認產生的構件 (JSON IR)
和所有繫結) 皆與先前審查的黃金檔案相同。
FIDL 版本管理的做法很類似。將針對小型螢幕進行單元測試
就是 fidlc 中的邏輯例如,您的測試能確保
資料表成員的
註解表示此問題是在表格本身之前推出。這項屬性會使用
但不要擴充現有的黃金測試架構。
為每個版本產生程式庫構件,會佔用黃金檔案
並導致難以驗證正確性這項專案將有專屬的
在每個版本中,具有 JSON IR 最佳「差異」的 .fidl
檔案集。這個
,驗證版本管理功能是否如預期運作。
這會讓平台 API 的實作者更難進行測試,而測試會
針對 HEAD
,就像我們目前不會針對 FIDL 執行測試一樣
舊 Git 修訂版本中的檔案也不會讓 SDK 使用者更難進行測試:
用於測試單一平台版本
目前的測試版本。
說明文件
@available
語法會以 FIDL 語言記錄
規格。請務必提供更多文件
發布新 API 級別的程序。比方說
程式庫作者在新增 API 時使用 @available(added=HEAD)
元素。只要妥善搭配,就不會有危險
而負責任的 AI 技術做法
有助於達成這項目標詳情請參閱「政策」一節。
此外,我們還需要從 FIDL 移除 [Deprecated]
屬性
屬性網頁的資訊,因為供應情形屬性已過時。
需更新 FIDL 來源相容性說明文件 以顯示使用供應情形屬性進行 FIDL 變更,或顯示如何顯示 並在使用版本管理功能時套用不同類型的 FIDL 差異。說明文件 也應說明 FIDL 版本管理對於轉換的整體互動方式。 使用版本管理功能後,無論何時使用 FIDL 元素,變更都一樣簡單 是否在樹狀結構外。這樣應該可以減少需要某種程度的軟音 轉場效果但不會清除所有多步驟轉換。它只是 在協調時移除單一共用時間軸的限制。
缺點、替代方案和未知
執行這個提案需要支付哪些費用?
此提案增加了 FIDL (語言) 和 fidlc 的複雜性。可讓您 對圖書館作者來說,要進行簡單安全的變更也更加困難 而做出其他類型的變更 (例如將成員新增至嚴格的列舉) 並採用可靠的專業技術
替代做法:使用舊版 SDK
FIDL 版本設定可讓應用程式保持使用舊版 API 級別, 持續推出新的 SDK但為何不直接使用舊的 SDK, 不需要整份提案?這有幾個原因:
- 有了最新的 SDK,使用者就能取得所有其他項目的最新副本,例如 做為 FIDL 工具鍊
- 目標 API 級別是依元件指定。針對各個類別使用不同的 SDK 複雜性又不切實際
替代方法:變更記錄檔案
不能使用供應情形屬性,而是透過個別的變更記錄將
包括 FIDL 程式庫的歷史記錄其中一種做法是
並將每個 .fidl
檔案還原為原始狀態。這麼做可簡化
例如難以管理 FIDL 屬性
無法一次驗證程式庫的所有版本,如提議所述
設計。不過,這種方法不需要,因為這個替代方法會消除
改變歷史的困境但這也讓使用者
並回答以下問題:「這個元素是什麼時候推出?」會
基本上是重複的 Git 歷史記錄,但主要差異在於
會在建立可下載 SDK 時保留。
若變更 FIDL 語法,則難以維護文字差異
另一個變更記錄檔設計的變化版本則會定義新的
格式來記錄 FIDL 程式庫的變更,以及發生版本變更的時間。
此設計與一次驗證所有版本相容,因為 fidlc
可以讀取變更記錄並產生暫時分解的 AST
來自屬性的資訊不過,這種做法
工具例如,我們可能希望開發人員能像原樣編輯 .fidl
檔案
並執行一項工具,以便在提交變更前附加至變更記錄檔案。
替代版本:每個程式庫版本
另一種設計是為每個 FIDL 程式庫提供獨立版本。這個
因此,系統會從 API 級別對應至每個 FIDL 程式庫的版本
將機器學習工作流程自動化舉例來說,API 級別 42 可能代表 fuchsia.auth
v1.2、
fuchsia.device
v5.7 等。
這種方法對於使用個別程式庫的開發人員來說有優勢。 對程式庫而言,每個版本都是有意義的,您可以 預測程式庫與目前版本號碼相比的進出程度。於 而個別平台版本之間則可能很長 程式庫中的某些變更
但它會引發許多問題。是否有個別程式庫版本代表 SDK 程式庫必須追蹤其依附的其他 SDK 程式庫版本嗎?可以 SDK 客戶會混合搭配不同版本的 SDK 程式庫?回應中 包含「是」這會使 FIDL 版本管理變得更為複雜。我們如何得知 會搭配運作嗎?我們如何避免編譯多份副本 相同程式庫的繫結之間?如果兩個答案皆為「否」: 每個程式庫的版本管理似乎無妨, 版本管理則會在程式庫層級進行。
替代方案:非對稱式淘汰
生命週期部分的 RFC-0002 狀態:
該元素可能會遭到淘汰。指定舊版 ABI 修訂版本的元件 在較新的平台版本上執行時,仍可使用此元素。不過 指定較新的 API 級別的開發人員將無法再使用該元素。
說明這對 FIDL 的影響:
通訊協定元素 (例如表格中的欄位或通訊協定中的訊息) 出現時 在特定 API 級別淘汰的元件 理想情況下,目標為 這個 API 級別才能接收包含該通訊協定元素的訊息 但希望能防止這些元件傳送 該通訊協定元素
FIDL 版本設定從此行為出發,因此會包含在此處
。防止開發人員在特定 API 上使用 FIDL 元素
級別,同時允許 Fuchsia 平台中的程式碼在執行階段提供支援
難以執行的程序正如先前所述,它仰賴了 Fuchsia 的錯誤假設
平台一律是伺服器,SDK 使用者一律是用戶端。
在某些情況下,這些角色的角色會變換,甚至模稜兩可。我們可以
藉由介紹 @platform_implemented
和
@user_implemented
。這樣有助於處理方法,但對型別的非對稱行為會有幫助
和型別成員 (下方稱為類型元素) 更難解決。
要達成不對稱式淘汰型別元素的方法之一,就是產生虛設常式
進而避免使用這類行為舉例來說,已淘汰的資料表欄位可能會顯示在
繫結做為 FidlDeprecated
類型的值,可產生類型檢查
發生錯誤。Fuchsia 平台的程式碼繼續支援
透過新的 fidlgen 旗標 --allow-deprecated
產生已淘汰的元素
就像無已淘汰一樣但這種方法有兩個問題。
第一,難以排除在清單中使用已淘汰的元素
Fuchsia,因為先前顯示為已淘汰。其次,要輕鬆
給實開發人員使用 標記如此一來,
獎勵:
這種做法鼓勵開發人員淘汰已淘汰 將新 API 的存取權搭配在一起以執行這些遷移作業。 具體來說,如要存取新導入的 API,開發人員必須 變更目標 API 級別,此時機構就必須 介面。
也就是說,開發人員可透過 --allow-deprecated
存取
只要使用 旗標,便不必遷移已淘汰的 API
型別元素的另一種方法是在執行階段產生錯誤。適用對象 舉例來說,如果資料表欄位已淘汰,繫結可能會在 編碼 (但保持不變)。不過 超出這個提案的執行階段行為範圍。
總而言之,非對稱式淘汰過於細微且複雜,不容易被納入 這個提案這些挑戰也許可以在未來的 RFC 中解決 不對稱式淘汰的好處相當複雜
替代版本:完整歷史紅外線
根據本提案,版本資訊只有在 JSON IR 前才提供。一次
我們已產生 IR,目前使用的是修正版本。這是
就足以產生繫結,但對 fidldoc 這類工具而言較不實用
可能會想使用版本資訊這些工具不是剖析這些工具
.fidl
檔案,或比較多個版本的 JSON IR
替代方法是導入新的 JSON IR 模式,
包含所有記錄和可用性資訊。與單純
會在 IR 中加入供應情形屬性,因為這意味著
這個替代方式有兩個問題。首先,這並不正確
JSON IR 檔案的結構定義和用途應與其他檔案稍有不同。
設計全新格式或許會比較好,但這也有缺點。
其次,要決定完整歷史流向,很難確定
完全不需要使用 UI fidldoc。舉例來說
是否會針對新增及移除 resource
修飾符 10 次的類型顯示相關資料?
關於這類問題及運用方式,我們會更妥善地解決
不同的 RFC。
既有藝術品和參考資料
此提案是 RFC-0002: Platform 所製定整體計畫的一環 版本管理:解讀 RFC 相當重要 背後的背景資訊和動機不但先進的藝術與 參考資料本節著重在其他作業系統: Android、Windows 和 macOS/iOS這裡我們會著重介紹其他程式設計語言 以及 IDL 的 API 版本管理方法
Swift、Objective-C
Swift 使用的 @available
屬性與屬性中的屬性很類似
和 Objective-C 採用類似的 API_AVAILABLE
屬性。
僅限於以硬式編碼的方式列出 Apple 平台 (例如 macOS 和 iOS)。
客戶也可使用 swift
平台,根據以下項目控管可用性:
編譯期間使用的 Swift 語言版本。版本指定為
1、2 或 3 個數字 (由 semver 語意後方分隔)。兩者皆有
語言所提供的語法也很類似,可在執行階段檢查平台版本。
荒漠油廠
Rust 會以穩定性屬性為標準程式庫加上註解
#[stable]
、#[unstable]
和#[rustc_deprecated]
。每個不穩定的元素都是
,且僅供選擇接受 GitHub 問題的開發人員使用
對應的 #[feature]
屬性。穩定版屬性代表 Rust
版本。不過
說明文件;但無法控制瀏覽權限
Protobuf、gRPC
通訊協定緩衝區並未提供版本管理工具。而是在 比 FIDL 更能注重前向與回溯相容性。例如: 不含結構體 (只有「messages」,如同 FIDL 資料表) 則沒有嚴格 所有類型 (所有類型都具有彈性行為),且不支援全面比對 列舉 (截至 proto3 為止)。
Google Cloud API 搭配 gRPC 使用通訊協定緩衝區,並提供 版本管理和相容性。 版本管理策略是以慣例為基礎,而非系統內建的功能。 API 會在 protobuf 套件的結尾處為主要版本號碼進行編碼,且 將其加入 URI 路徑如此一來,服務就能支援多個 版本進行更新,用戶端就能取得回溯相容的更新。 也就是不採取行動遷移。