RFC-0239:實際平台版本管理

RFC-0239:平台版本管理實務
狀態已接受
區域
  • 一般
  • 管理事宜
說明

Fuchsia 的概念模型和相容性保證。

Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2023-11-08
評論日期 (年-月-日)2024-01-30

摘要

本 RFC 的目標是擴充 RFC-0002、RFC-0083 等,具體做法如下:

  • 提出概念模型,說明 API 級別和 ABI 修訂版本在 Fuchsia 上的實際使用方式
  • 向合作夥伴提供 API 和 ABI 相容性保證 (以該概念模型表示),以及
  • 說明我們如何確保相容性。

簡要說明:

  • 每個 Fuchsia 里程碑都有對應的 API 級別。API 級別 15 可視為「Fuchsia 平台介面的第 15 版,最初由 F15 支援」。
  • 每個 Fuchsia 版本都支援多個 API 級別。舉例來說,F15 里程碑版本支援 API 級別 11、12、13、14 和 15。
  • 終端開發人員在建構元件時,會選取單一目標 API 級別。指定 API 級別 13 的元件會看到 API 級別 13 的 Fuchsia 平台介面原貌,並在支援 API 級別 13 的任何 Fuchsia 系統上執行。
  • Fuchsia 核心和平台元件同時實作多個 API 級別,因此可支援這些級別。

提振精神

如 RFC-0227 所述,Fuchsia 平台版本的主要元件包括:

  • Integrator Development Kit (IDK):一組小型程式庫、套件和工具,用於建構及執行 Fuchsia 專用元件。
  • 作業系統 (OS) 二進位檔,包括核心、開機載入器、套件、工具,以及設定和組合 Fuchsia 產品組合所需的其他元素。

IDK 是 Fuchsia SDK 的前身,與建構系統無關,用於描述構成 Fuchsia 平台介面的 API 元素 (例如通訊協定、方法、欄位、引數、程式庫),並允許終端開發人員編寫使用這些 API 元素的元件。IDK 中的部分介面是由核心和平台元件等 OS 二進位檔實作,其他介面則由外部元件 (例如應用程式或驅動程式) 實作,並預期 OS 二進位檔會呼叫這些介面。

Fuchsia 平台介面會持續開發,OS 二進位檔也會隨之更新。這些變更會快速1向下傳遞給終端開發人員和產品擁有者。在推出 API 級別之前,IDK 僅包含平台介面的單一說明。週一建構的 IDK 所描述的 Fuchsia 平台介面版本,會與當週週五建構的 OS 所實作的版本不同。這在過去會造成問題:如果 FIDL 方法及其導入作業在週三刪除,使用週一 IDK 建構的外部元件可能會嘗試呼叫該方法,但週五的 OS 會告知該方法不存在。

最簡單的做法是禁止 IDK 和 OS 版本不相符。我們可以說,OS 只會執行使用完全相同 Fuchsia 版本 IDK 建構的元件 (也就是說,OS 版本 2.20210213.2.5 只會執行使用 IDK 版本 2.20210213.2.5 建構的元件)。不過,這並不可行,因為我們無法要求終端開發人員在我們發布新版 Fuchsia 時,不斷更新及重建元件。因此,一般來說,建構外部元件的 IDK 和執行這些元件的 OS 可能來自不同的 Fuchsia 版本,甚至可能來自不同的里程碑。

這引出一個問題:在什麼情況下,使用某個版本 IDK 建構的元件,能在另一個版本的 OS 上成功執行?

RFC-0002 導入 API 級別和 ABI 修訂版本,做為協助回答這個問題的工具,但並未具體說明實際使用方式,也未提供具體的相容性保證。本 RFC 說明 API 級別和 ABI 修訂版本的實際使用方式、建立相容性保證政策,並簡要討論遵守該政策的策略,藉此填補這些落差。

相關人員

引導者:jamesr@google.com

審查者:

  • abarth@google.com
  • ianloic@google.com
  • mkember@google.com
  • yaar@google.com

諮詢對象:

  • chaselatta@google.com
  • ddorwin@google.com
  • sethladd@google.com

社交:

這份 RFC 中的模型和政策在過去幾年逐步建立,但尚未編碼至任何 RFC。這項提案是透過許多文件和對話達成,主要是在平台版本管理工作小組成員之間進行。

假設

描述公開 API 的元件與使用該 API 的另一個元件之間的相容性時,我們假設互動的一端是樹狀結構外建構的外部元件 (也就是透過 IDK 在 Fuchsia 平台建構外建構),而互動的另一端則是樹狀結構內建構的 OS 二進位檔 (例如核心或 Fuchsia 平台元件,也就是在 Fuchsia 平台的 GN 建構圖中建構)。定義外部元件之間互動的版本管理做法和相容性,不屬於本文件範圍,留待日後處理。

設計

本節將說明 Fuchsia 平台版本管理背後的概念模型。本文所述的許多概念先前已在 RFC-0002 中介紹過,但此處會提供更具體的細節和限制。

本「設計」一節的文字應視為資訊,而非規範。下方的「政策異動」部分會重複顯示本文字中代表現有政策異動的部分。

API 等級

Fuchsia 平台介面會不斷變更,且新的 Fuchsia 版本會不斷建立,一天多次。如果必須考量每個 Fuchsia 版本與其他版本 Fuchsia 平台介面的相容性,會過於繁雜,因此我們只會考量版本與有限數量 API 級別的相容性。

您可以將 API 級別視為構成 Fuchsia 平台介面的 API「版本」、「版本」或「快照」。API 級別 10 是「Fuchsia API 介面的第 10 版」。API 級別會與里程碑同步,因此 API 級別 10 也可以視為「F10 發布時 Fuchsia 平台介面的最新版本」。

您可以使用 API 級別來做出聲明,例如「fuchsia.lightsensor.LightSensorData FIDL 資料表在 API 級別 10 中有三個欄位 (rgbc、calculated_lux 和 correlated_color_temperature),但在 API 級別 11 中新增了兩個欄位 (si_rgbc 和 is_calibrated)。自 API 級別 11 起,該資料表有五個欄位,但我們可能會在 API 級別 16 中移除部分欄位或新增更多欄位。」

就像教科書的版本一樣,API 級別不可變更。教科書的內容可能會隨著時間而改變,但第 2 版教科書的內容在出版後就不會再變更。這表示任何兩個 Fuchsia 版本只要知道指定的 API 級別,就會同意構成該 API 級別的 API 元素組合。

Fuchsia 平台介面不限於 FIDL,也包含系統呼叫、C++ 程式庫和其中的方法、永久檔案格式等。在概念上,這些都是依 API 級別建立版本,但實際上,FIDL 程式庫的版本管理支援,比 Fuchsia 平台介面的其他方面更為先進。

指定 API 級別

終端開發人員在建構元件時,會選取單一目標 API 級別。如果開發人員指定目標 API 級別 11,其元件將可存取 API 級別 11 中可用的 API 元素。如果方法是在 API 級別 12 中新增,元件就不會在產生的繫結中看到該方法。相反地,如果 API 級別 11 的方法在 API 級別 12 中「移除」,元件「仍可」繼續使用該方法。

建構元件時,IDK 中的工具會將目標 API 級別的相關 ABI 修訂版本嵌入元件套件中。這通常稱為元件的「ABI 修訂版本戳記」。

ABI 修訂版本戳記可確保元件觀察到的執行階段行為 ,與目標 API 級別指定的行為相符。目前,ABI 修訂版本戳記的使用方式非常粗略:如果 OS 支援該 ABI 修訂版本對應的 API 級別,元件就能執行。否則 (例如外部元件指定 API 級別 11,但 OS 二進位檔不再實作 API 級別 11 的方法),元件管理服務會阻止該元件啟動。

版本和階段

每個 Fuchsia 版本都支援多個 API 級別,並為每個 API 級別指派階段。如要查看 Fuchsia 版本中的 API 級別,請下載其 IDK,並查看 version_history.json 檔案。

舉例來說,假設 Fuchsia 版本 20.20240203.2.1 可能包含:

  • API 級別 17、18 和 19 處於支援階段。這表示 IDK 版本 20.20240203.2.1 可建構指定任何這些 API 級別的元件,而 Fuchsia 版本 20.20240203.2.1 可執行指定任何這些 API 級別的元件。大多數情況下,多數終端開發人員應指定支援的 API 級別。
  • API 級別 15 和 16 處於淘汰階段。Fuchsia 仍會執行指定淘汰 API 級別的元件,但 IDK 在建構元件時,將不再支援指定這些級別。

這個假設的 version_history.json 也會在「已停用」階段列出 API 級別 14 以下版本。Fuchsia 不會建構或執行指定已淘汰 API 級別的元件,但會保留這些元件供日後參考。

API 級別會在支援階段發布,時間點就在對應的里程碑分支版本推出前不久。上述假設的 20.20240203.2.1 初期測試版是在 API 級別 20 發布前推出,因此 API 級別 20 明顯缺席。在 F20 分支版本推出前不久,API 級別 20 將會發布,後續版本 (例如 20.20240301.4.1) 會將 API 級別 20 列為「支援」。具體來說,所有里程碑版本都會在支援階段納入對應的 API 級別。

當我們決定停止支援某個 API 級別時,會先將其移至淘汰階段。這會建立一種後端停止機制,現有指定該 API 級別的二進位檔會繼續執行,但不會建立指定該 API 級別的新二進位檔 (至少不會使用新版 IDK)。一旦所有指定特定 API 級別的現有二進位檔都已淘汰,我們就可以停用該級別。

API 級別不會按照特定時間表淘汰或停用。相反地,當合作夥伴不再針對某個 API 級別建構應用程式時,我們就會淘汰該 API 級別;當合作夥伴不再希望執行指定該 API 級別的二進位檔時,我們就會停用該 API 級別。未來,隨著合作夥伴數量增加,我們可能無法密切關注個別需求,屆時就需要更正式的政策,但目前這樣就足夠了。

NEXT 和 HEAD 虛擬 API 級別

除了上述 API 級別外,還有兩個特殊的「可變動」虛擬 API 級別:NEXT 和 HEAD。

與其他 API 級別不同,NEXT 和 HEAD 的內容可以從一個版本到另一個版本任意變更。API 元素可以新增、修改、替換、淘汰和/或移除。原則上,20.20240203.1.1 中的 NEXT 可能與 20.20240203.2.1 中的 NEXT 完全不同,但實際上,變更會是漸進式的。

如 RFC-0083 所述,HEAD 代表開發的最新版本,適用於樹狀結構內用戶端 (例如其他平台元件或整合測試),不保證穩定性。HEAD 中導入的 API 元素可能甚至無法運作;例如,HEAD 的通訊協定可能已新增方法,但通訊協定伺服器可能尚未實際實作該方法。

NEXT 代表下一個編號 API 級別的「草稿」版本。在每個里程碑分支版本剪輯前不久,我們會將 NEXT 的內容發布為新的 API 級別。在機制上,我們會建立變更清單,將 FIDL 註解和 C 預處理器巨集中的 NEXT 執行個體,替換為下一個里程碑分支版本的特定編號。NEXT 中的 API 元素應可正常運作,且在下一個 API 級別發布前「不太可能」變更,但仍有可能變更。

在 RFC-0083 的語言中,HEAD 比 NEXT 新,這表示 NEXT 中的所有 API 變更也包含在 HEAD 中。

終端開發人員可以指定 HEAD 或 NEXT,但這樣做會使 API 和 ABI 相容性保證失效。如要進一步瞭解從樹狀結構外指定 NEXT 或 HEAD 的影響,請參閱說明這些保證的章節。

政策異動

本節列出這份 RFC 提出的具體政策異動。

模型異動

這項 RFC 對平台版本管理模型進行了下列變更:

  • 編號 API 級別現在不可變更。除了特殊的「開發中」API 級別外,所有 API 級別在實務上都已具備這項屬性。這項 RFC 實際上會淘汰「開發中」API 級別,改用 NEXT。
  • 導入 API 級別階段。「支援」和「停用」已在實際情況中存在,但後者目前稱為「不支援」。這份 RFC 建議重新命名,並加入「sunset」。
  • 介紹 NEXT。這是另一個特殊 API 級別,類似 HEAD。HEAD「新於」NEXT。這會取代目前將最新 API 級別指定為「開發中」API 級別的做法。
  • 允許對 NEXT 進行回溯不相容的變更。目前的政策是由工具強制執行,但未在任何 RFC 中建立,因此只能對開發中的 API 級別進行回溯相容變更。這項 RFC 移除該限制,且不會套用至 NEXT。詳情請參閱下文。
  • 將 API 級別與里程碑連結。API 級別 N 會在 FN 里程碑分支版本剪輯前不久建立,並以 NEXT 的內容為基礎。這在實務上確實如此,但尚未在任何 RFC 中獲得批准。
  • API 級別會盡快進入各個階段,具體時程取決於合作夥伴。只要合作夥伴不再需要建構指定該 API 級別的二進位檔,我們就會立即淘汰該 API 級別。只要沒有合作夥伴想在新版 Fuchsia 上執行指定該 API 級別的二進位檔,我們就會立即淘汰該 API 級別。

API 相容性保證

Fuchsia 現在針對編號 API 級別提供下列 API (即建構時) 相容性保證 (須遵守下方注意事項):

如果終端開發人員能使用「某個」IDK 版本,成功建構指定編號 API 級別 N 的元件,就能使用「任何」IDK 版本 (N 處於支援階段),成功建構相同的原始碼。

換句話說,在所選目標 API 級別淘汰前,終端開發人員可以放心升級或復原 IDK,不必擔心建構作業中斷。如果更新至其他 IDK,但未變更目標 API 級別,導致建構作業中斷 (例如使用的 API 元素已不存在),則會視為 Fuchsia 平台錯誤。

另一方面,可變動的虛擬 API 級別 NEXT 和 HEAD 則「不」保證 API 相容性。指定 NEXT 或 HEAD 時,終端開發人員可能會發現更新 IDK 會導致程式碼無法編譯。

實際上,我們目前的合作夥伴與 Fuchsia 團隊密切合作,我們會盡可能避免破壞以 NEXT 為目標的終端開發人員建構作業。我們不會特別避免破壞指定 HEAD 的終端開發人員建構作業。

ABI 相容性保證

Fuchsia 現在針對編號 API 級別提供下列 ABI (即執行階段) 相容性保證 (請參閱下方注意事項):

如果元件是針對編號 API 級別 N 建構,則可在任何 Fuchsia 版本上成功執行,且 N 處於支援或淘汰階段,而且版本之間不會出現任何令人反感的行為變更。

換句話說,終端開發人員不需要變更或重新編譯程式碼,就能在較新版本的 Fuchsia 上執行,直到所選目標 API 級別淘汰為止。如果平台在不同 Fuchsia 版本上的行為不同,導致元件功能受到干擾,就會視為 Fuchsia 平台錯誤。

另一方面,對於指定可變動虛擬 API 級別 NEXT 或 HEAD 的元件,則「不」保證 ABI 相容性。只有在 Fuchsia 的執行版本與建構 IDK 的版本完全比對時,系統才會允許執行針對 NEXT 或 HEAD 建構的元件。舉例來說,如果元件指定 NEXT,並使用 IDK 版本 16.20231103.1.1 建構,則可在 Fuchsia 版本 16.20231103.1.1 上執行,但不會 (預設) 在 Fuchsia 版本 16.20231103.2.1 的裝置上執行。

在大多數情況下,無法確保建構元件的 IDK 版本與執行元件的 OS 版本完全相符。整合測試和本機實驗是值得注意的例外狀況。樹狀結構外存放區通常可以控制要使用哪個版本的 IDK 進行編譯,以及要使用哪個版本的 OS 進行測試。如果想在 NEXT 或 HEAD 中測試功能,應讓兩者保持同步。

禁止使用不支援的設定

根據預設,如果元件的 ABI 修訂版本戳記指出該元件不在 ABI 相容性保證範圍內,component_manager 會拒絕啟動該元件。具體情形如下:

  • 只有在 N 受到支援或已淘汰的情況下,特定 Fuchsia 版本才會執行指定 API 級別 N 的元件。
  • 如果 Fuchsia 的特定版本是使用完全相同版本的 IDK 建構而成,則只會執行指定 NEXT 或 HEAD 的元件。

同樣地,產品組裝也會拒絕組裝與平台不相容的元件。

產品擁有者可以選擇停用這些檢查。舉例來說,即使建構 IDK 的 Fuchsia 版本不同,他們仍可將個別元件加入許可清單,指定 NEXT 或 HEAD。產品擁有者須自行承擔停用這些檢查的風險。

實作

如要實作這些檢查,必須對 ABI 修訂版本戳記進行一些變更。這些變更的完整設計超出本 RFC 的範圍,但簡而言之:

  • 與目前的情況一樣,每個 API 級別在發布時都會指派專屬的 ABI 修訂版本。指定編號 API 級別的元件,會標上該 API 級別對應的 ABI 修訂版本。
  • 此外,每個版本都會指派專屬的 ABI 修訂版本。指定 HEAD 或 NEXT 的元件會加上這個每個版本 ABI 修訂版本的戳記。

特定版本中的 OS 二進位檔會包含所有 API 級別在支援或淘汰階段的 ABI 修訂版本清單,以及該版本的 ABI 修訂版本。根據預設,只有標記其中一個 ABI 修訂版本的元件才能執行。

未來擴充功能

請注意,「每個 API 級別一個 ABI 修訂版本,加上 NEXT/HEAD 的一個修訂版本」的安排不一定是這項設計的最終版本。ABI 修訂版本是我們以機器可讀的方式,對 ABI 相容性保證進行編碼的方式,因此如果我們的保證變得更細緻,ABI 修訂版本的分配也必須更細緻。

舉例來說,假設我們將部分 API 介面指定為「長期支援 (LTS)」,並在 API 級別內繼續支援 LTS API,時間比其他 API 更長。假設 F30 版本可能支援 API 級別 25 的 LTS API,但不支援非 LTS API。該版本只能使用 LTS API 執行指定 API 級別 25 的元件,但無法執行指定 API 級別 25 且使用非 LTS API 的元件。因此,這兩種元件需要加上不同的 ABI 修訂版本,我們可以為每個 (API 級別、LTS 狀態) 組合提供專屬的 ABI 修訂版本。

我們對此有一些想法,如果決定採用,會在後續的 RFC 中說明。

平台元件同時支援所有支援的 API 級別

目前我們沒有任何機制,可讓平台元件根據連線另一端元件的 ABI 修訂版本戳記,改變其行為,因此支援多個 API 級別,代表同時支援多個 API 級別。平台元件的行為必須符合支援或淘汰階段中各 API 級別的規格。

更精確地說,平台元件不得對外部元件指定的 API 級別做出任何假設,除非該元件指定的是支援或已淘汰的 API 級別。

舉個簡單的例子,如果方法 Foo 在 API 級別 15 從 FIDL 通訊協定中移除 (也就是 Foo 加上 @available(added=A, removed=15) 註解),但 API 級別 14 仍受支援,則實作相關通訊協定伺服器的平台元件必須繼續實作 Foo,直到包含該方法的所有 API 級別都已淘汰。

反之,如果該 FIDL 通訊協定伺服器是由樹狀結構外驅動程式庫實作,則與該驅動程式庫通訊的平台元件必須正常運作,無論驅動程式庫是否實作 Foo。

這項策略不僅限制平台元件的實作,也限制我們對平台介面進行的修改類型。理論上,API 可能會因 API 級別而任意變更,但實際上,某些變更 (例如重複使用 FIDL 通訊協定方法序數) 會導致我們無法在沒有進一步資訊的情況下,與指定不同 API 級別的外部元件正確通訊。

我們可能會開發不同的策略來支援多個 API 級別,但這是未來的工作。

注意事項

API 和 ABI 相容性保證均受限於一些注意事項。

「保證」的意義

「保證」相容性並不代表 Fuchsia 絕對不會違反相容性承諾,畢竟人非聖賢。也就是說,如果我們根據上述條款破壞相容性,我們會將其視為錯誤。我們會負責在內部修正問題,終端開發人員除了回報錯誤外,不需採取任何行動。

保證失效

如果終端開發人員「做出奇怪的行為」,則不適用 API 和 ABI 保證。不當的導入方式包括但不限於:

  • 修改 IDK 副本中的檔案,
  • 存取內部命名空間中的成員
  • 手動合成應由 IDK 程式庫建構的資料
  • 將不同 IDK 建構的共用程式庫連結至單一二進位檔
  • 依此類推

值得注意的反例是,依賴 Fuchsia 中的錯誤行為不算「做奇怪的事」。在某些情況下,修正錯誤可能會被視為「令人反感的行為變更」。詳情請參閱「令人反感的變更」一節。

本 RFC 不會完整列出所有禁止行為。套用美國最高法院大法官 Potter Stewart 在 Jacobellis 訴俄亥俄州案中的話:「我今天不會進一步嘗試定義『做奇怪的事』,而且我可能永遠無法成功地清楚定義。但我一看到就會知道。」

令人反感的變更

ABI 相容性保證承諾,在支援元件目標 API 級別的 Fuchsia 版本之間,元件不會出現「令人反感的行為變更」。「令人反感」的定義顯然是主觀的,某些人認為理想的變更,可能對其他人來說是令人反感的 (相關 xkcd)。最終,系統會根據個案情況,處理令人反感的行為變更檢舉。

安全性和隱私權

如果事後發現 Fuchsia 平台介面的某些部分有重大安全性或隱私權問題,我們可能會選擇停止支援有問題的功能,以達成安全性與隱私權目標。

效能

維持與舊版 API 級別的回溯相容性會耗費效能。至少,回溯相容的平台二進位檔必須更大,因為會保留更多邏輯。在某種程度上,這是不可避免的,但 API 級別會自動淘汰,可能會使問題更加嚴重。

回溯相容性

這份 RFC 的所有內容都與回溯和向前相容性有關。

測試

測試以確保 API 和 ABI 相容性是另一個重要主題。

Fuchsia 相容性測試 (CTF) 的目標是提供測試涵蓋範圍,確認我們符合 ABI 相容性保證。目前涵蓋率偏低,但我們正積極改善。

目前,我們無法編寫測試來驗證 API 相容性保證;所有樹狀結構內測試都是針對 LEGACY API 級別建構,因此我們無法複製樹狀結構外客戶指定編號 API 級別的體驗。這個問題需要解決,但解決問題不應阻礙這項 RFC 的接受。

說明文件

本 RFC 經批准後,其文字將重複使用,做為多份文件的基礎,供 Fuchsia 平台開發人員參考:

此外,文件也需要更新,反映現有概念的重新命名。

缺點、替代方案和未知因素

缺點:API 級別是不可部分完成的

如 RFC-0002 所述,API 級別涵蓋整個 Fuchsia 平台介面。因此,API 級別階段的變更 (例如淘汰 API 級別) 會影響整個 API 級別,我們無法只淘汰部分功能。同樣地,如果終端開發人員指定特定目標 API 級別,則會指定整個 Fuchsia 平台介面的目標 API 級別;例如,他們無法指定大多數 API 的 API 級別 13,但指定特定 API 的 API 級別 16。

未來擴充平台版本管理模型時,可能會允許有意義的細分,但 IDK 中各種程式庫之間的依附元件會使這項作業變得困難。

替代方案:不設淘汰階段

這份 RFC 的早期草稿省略了淘汰階段,將其列為「未來可能的工作」。淘汰階段是模型非常合理的延伸,而且在討論中經常被提及,因此主動納入似乎是合適的做法。

替代方案:其他可能的虛擬 API 級別

如上所述,HEAD 有多種潛在用途:樹狀結構內元件之間的通訊、向整合測試公開的 API、實驗性 API 等。這些是否應以不同的虛擬 API 級別表示?

這份 RFC 建議先從 NEXT 和 HEAD 開始,但在指派數值時,在兩者之間留出空隙。這樣一來,如果我們發現有其他用途,就可以新增更多虛擬 API 級別。

替代方案:回溯相容的開發中 API 級別

Fuchsia 的實際版本管理政策目前規定,只能對開發中的 API 級別進行回溯相容變更。這項 RFC 會復原該政策,因此當終端開發人員指定 NEXT 時,不保證不同版本的 IDK 和 OS 二進位檔之間的相容性。

如果我們在開發中的 API 級別 (或 NEXT) 內維持這項回溯相容性政策,就能做得更好:只要 OS 二進位檔來自比 IDK 更新的版本,我們就能保證 IDK 和 OS 二進位檔相容。直到最近,我們才將下游存放區移至目標支援的 API 級別,不再依賴這項屬性。

這樣一來,終端開發人員就能在新的 Fuchsia 功能加入開發中的 API 級別後,安全地開始依賴這些功能,不必等待該 API 級別發布。

不過,這會大幅增加系統的複雜度:

  • Fuchsia 平台開發人員不僅必須維持與先前 API 級別的回溯相容性 (其 API 簽章編碼在 FIDL 和標頭檔案本身),也必須維持與先前開發中 API 級別版本的回溯相容性 (其 API 簽章未編碼在 FIDL 和標頭檔案本身)。查看這些舊版本的唯一方法是檢查 git 記錄,但實際上不會發生這種情況。
  • 由於我們需要能夠從平台中移除功能,因此必須有某些 API 級別支援回溯不相容的變更。這表示 Fuchsia 平台開發人員必須在開發中 API 級別之後,對編號 API 級別進行回溯不相容的變更。因此,實際上會有兩個開發中的 API 級別,Fuchsia 平台開發人員必須同時考量這兩個級別。
  • 這會大幅提高 ABI 修訂版本的複雜度。為了在開發中的 API 級別內支援回溯相容變更,我們需要無限期保留每個版本的 ABI 修訂版本 (每天會建立多個版本)。OS 二進位檔必須支援每個版本 (其中一個支援的 API 級別是開發中的 API 級別) 的 ABI 修訂版本,以及目前里程碑至今所有版本的 ABI 修訂版本。以目前的發布頻率來看,每個 API 級別大約會增加 168 個 ABI 戳記,而截至本文撰寫時,Fuchsia 的版本需要支援超過 800 個 ABI 戳記。雖然這類解決方案的記憶體成本不太可能很高,但目前看來,維護與數百、數千或數萬個不同 ABI 的相容性,其複雜度似乎不值得,尤其是目前沒有任何客戶使用開發中的 API 級別。

這份 RFC 不排除日後提供額外相容性保證的可能性。

替代方案:將 API 級別與里程碑分離

這份 RFC 明確將 API 級別與里程碑編號連結。這並非絕對必要,特別是 Android 會將兩者分離。Android 專案會使用這項能力,在發布 OS 子版本時一併推出 API 變更。例如,API 級別 24 對應 Android 7.0,API 級別 25 對應 Android 7.1。

在我的研究中,我沒有發現其他平台選擇這條路徑的例子。我發現其他平台會根據發布版本說明 API 元素的可用性,例如「自 Chrome 88 起提供」或「在 iOS 6.1 中淘汰」。

macOS 和 iOS API 級別與其版本管理配置相結合,但兩者都允許在次要修訂版本中變更 API,這與 Fuchsia 不同。不過,這似乎主要是為了將版本的主要版本與日曆年結合,同時仍允許每年多次發布 API 更新。

Fuchsia 的里程碑更接近 Chrome 的模式,會頻繁增加主要版本,並保留子版本不使用。如果想更頻繁地穩定 API 級別,可以更頻繁地增加 Fuchsia 的里程碑編號。

替代方案:編號的「開發中」API 級別

這份 RFC 的早期草稿與目前實作的平台版本管理模型較為接近。在該模型中,NEXT 不存在,而是編號最大的 API 級別是可變動的,稱為「開發中」API 級別。

從機械角度來看,這兩個模型只有一些細微差異:

  1. 目前,Fuchsia 平台開發人員會選擇特定 API 級別,以便推出功能。實作這項 RFC 後,他們會對 NEXT 進行正式版 API 變更,並在下一個編號的 API 級別中自動發布。
  2. 目前,如果終端開發人員指定開發中的 API 級別,系統會在該 API 級別發布後,自動轉換為指定該 API 級別的支援版本。這項 RFC 實施後,仍會繼續指定 NEXT。

這些差異似乎沒有明顯的好壞之分。

相較於開發中的 API 級別,NEXT 的主要優點是易於溝通。這份 RFC 的早期草稿採用了口頭技巧來表達相容性保證:「針對支援的 API 級別 N 建構的元件,可在支援階段中支援 API 級別 N 的任何 Fuchsia 版本上成功執行。」在目前的提案中,所有參與方都會同意特定 API 級別的內容,不需要任何限定詞。

替代方案:不移除任何內容

我們可以完全禁止回溯不相容的變更,簡化平台版本管理。每個 API 級別都會支援先前級別的所有功能,而「平台支援所有 API 級別」屬性則會因為支援最新 API 級別而「免費」提供。

許多平台 (包括 Windows 和 Android) 大多採用這種做法,但因此無法清除舊版 API 介面的殘留內容。

雖然 Fuchsia 平台工程師仍須支援舊版 API 元素 (只要這些元素出現在支援或淘汰的 API 級別中),但終端開發人員只需關注所選目標 API 級別的內容,不必查看不必要的內容。

此外,雖然「絕不移除任何內容」可能會讓版本管理變得更簡單,但絕不能完全解決問題。終端開發人員仍須根據預期安裝數中最舊的 Fuchsia 平台版本,判斷要指定的 API 級別。


  1. 我們的大多數下游合作夥伴目前都依賴 Fuchsia 的初期測試版,這些版本每天會產生多次。未來,更多合作夥伴將從里程碑版本分支使用 IDK 和 OS 二進位檔,但目前我們重視這項安排所帶來的即時意見回饋。 ↩