RFC-0239:實務中的平台版本管理 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 概念模型和 Fuchsia 相容性的保證。 |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2023-11-08 |
審查日期 (年-月-日) | 2024-01-30 |
摘要
本 RFC 的目標是擴充 RFC-0002、RFC-0083 和其他 RFC,具體做法如下:
- 並說明概念模型,說明在 Fuchsia 上實際使用 API 級別和 ABI 修訂版本的方式。
- 向合作夥伴提供 API 和 ABI 相容性保證,並以概念模型的形式說明。
- 說明我們如何實現這些相容性保證。
簡要說明:
- 每個 Fuchsia 里程碑都會搭配API 級別。API 級別 15 可視為「F15 首次支援的 Fuchsia 平台介面第 15 版」。
- 每個 Fuchsia 版本都支援多個 API 級別。舉例來說,F15 里程碑版本支援 API 級別 11、12、13、14 和 15。
- 最終開發人員在建構元件時,會選取單一目標 API 級別。指定 API 級別 13 的元件會在 API 級別 13 中看到 Fuchsia 平台介面,並會在支援 API 級別 13 的任何 Fuchsia 系統上執行。
- Fuchsia 核心和平台元件會同時實作多個 API 級別,以便支援多個 API 級別。
提振精神
如 RFC-0227 所述,Fuchsia 平台版本的主要元件如下:
- 整合器開發套件 (IDK):一組小型程式庫、套件和工具,用於建構及執行以 Fuchsia 為目標的元件。
- 作業系統 (OS) 二進位檔,包括核心、啟動載入程式、套件、工具,以及設定及組合 Fuchsia 產品套件的其他必要元素。
IDK 是 Fuchsia SDK 的建構系統無關前身,可說明組成 Fuchsia 平台介面的 API 元素 (例如協定、方法、欄位、引數、程式庫),並讓最終開發人員編寫使用這些 API 元素的元件。IDK 中的部分介面是由作業系統二進位檔 (例如核心和平台元件) 實作,其他介面則是由外部元件 (例如應用程式或驅動程式) 實作,並預期作業系統二進位檔會呼叫這些元件。
Fuchsia 平台介面不斷開發中,作業系統二進位檔也會持續更新以配合。這些變更會快速1 流向下游,傳送給最終開發人員和產品擁有者。在導入 API 等級之前,IDK 只包含平台途徑的單一說明。在星期一建構的 ID 會描述不同版本的 Fuchsia 平台途徑,與在該週稍晚星期五建構的作業系統實作版本不同。這會導致問題:如果 FIDL 方法及其實作項目是在星期三刪除,使用星期一 IDK 建構的外部元件可能會嘗試呼叫該方法,但星期五的作業系統會告知該方法不存在。
我們可以嘗試禁止 IDK 和 OS 版本不相符。我們可以說,OS 只會執行使用相同 Fuchsia 版本的 IDK 建構的元件 (也就是說,OS 版本 2.20210213.2.5
只會執行使用 IDK 版本 2.20210213.2.5
建構的元件)。不過,這不切實際,因為我們無法要求最終開發人員在我們發布新版 Fuchsia 時,持續更新及重建其元件。因此,一般來說,用於建構外部元件的 IDDK 和執行這些元件的 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 平台版本之外) 的外部元件,而另一端則是建構於樹狀結構內 (也就是在 Fuchsia 平台的 GN 建構圖中建構) 的 OS 二進位檔,例如核心或 Fuchsia 平台元件。定義外部元件之間互動版本管理做法和相容性超出範圍,將留待日後處理。
設計
本節將說明 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 級別是immutable的。教科書內容可能會隨時間變更,但教科書第 2 版內容一旦發布,就不會再變更。也就是說,任何兩個瞭解特定 API 級別的 Fuchsia 版本,都會同意組成該 API 級別的 API 元素集。
Fuchsia 平台途徑不限於 FIDL,還包括系統呼叫、C++ 程式庫和其中的方法、持續性檔案格式等等。在概念上,這些都會依 API 級別進行版本控制,但實際上,Fuchsia 平台介面的其他層面,對 FIDL 程式庫的版本控制支援進度遠遠落後。
指定 API 級別
最終開發人員在建構元件時,會選取單一目標 API 級別。如果開發人員指定 API 級別 11,其元件將可存取 API 級別 11 中可用的 API 元素。如果在 API 級別 12 中新增方法,元件就不會在產生的繫結中看到該方法。反之,如果 API 級別 11 中的某個方法在 API 級別 12 中遭到移除,元件仍可繼續使用該方法。
在建構元件時,IDK 中的工具會將目標 API 級別的相關 ABI 修訂版本嵌入元件的套件中。這通常稱為元件的「ABI 修訂版本標記」。
有了 ABI 修訂版本記號,我們就能確保元件觀察到的執行階段行為,會與其目標 API 層級指定的行為相符。目前,ABI 修訂版本戳記的使用方式非常粗略:如果作業系統支援該 ABI 修訂版本的相應 API 級別,則可執行該元件。否則 (例如,如果外部元件指定 API 級別 11,但 OS 二進位檔不再實作 API 級別 11 的部分方法),元件管理服務就會防止其啟動。
版本和階段
每個 Fuchsia 版本都支援多個 API 級別,並為每個 API 級別指派階段。您可以下載 Fuchsia 版本的 IDK,然後查看 version_history.json
檔案,找出該版本的 API 級別。
舉例來說,假設 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 在建構元件時,將不再支援以這些 API 級別為目標。
這個假設的 version_history.json
也會在已淘汰階段列出 API 級別 14 及更早的級別。Fuchsia 不會建構或執行以已淘汰 API 級別為目標的元件,但會保留這些元件以供日後使用。
API 級別會在支援階段發布,也就是在對應里程碑分支版本推出前不久。上方假設的 20.20240203.2.1
Canary 版本來自 API 級別 20 發布之前,因此 API 級別 20 明顯缺少。在 F20 分支版本推出前不久,我們會發布 API 級別 20,後續版本 (例如 20.20240301.4.1
) 會將 API 級別 20 列為「支援」。具體來說,所有里程碑版本都會在支援階段納入相應的 API 級別。
當我們選擇停止支援某個 API 級別時,會先將該級別移至停用階段。這會建立某種備援機制:鎖定該 API 級別的現有二進位檔會繼續執行,但不會建立鎖定該 API 級別的新二進位檔 (至少不會使用 IDK 的新版本)。一旦所有指定特定 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 級別都已將這個屬性設為 true。這份 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
為目標建構的元件,會在任何支援N
或已停用的 Fuchsia 版本中成功執行,且不會在版本之間看到任何令人反感的行為變更。
換句話說,只要所選的目標 API 級別未淘汰,最終開發人員就不需要變更或重新編譯程式碼,即可在較新版本的 Fuchsia 上執行。如果平台的行為不同,以至於會干擾其元件在不同版本的 Fuchsia 上的功能,則會視為 Fuchsia 平台錯誤。
另一方面,如果元件指定可變動的偽 API 級別 NEXT
或 HEAD
,則沒有 ABI 相容性保證。以 NEXT
或 HEAD
為目標建構的元件,只有在執行的 Fuchsia 版本「完全」與建構時使用的 IDK 版本相符時,才能順利執行。舉例來說,如果元件指定以 NEXT
為目標,且以 IDK 版本 16.20231103.1.1
建構,就會在 Fuchsia 版本 16.20231103.1.1
上運作,但不會 (預設為) 在搭載 Fuchsia 版本 16.20231103.
2
.1
的裝置上運作。
在大多數情況下,確保用於建構元件的 IDK 版本與執行該元件的 OS 版本完全相符,是不可行的。值得注意的例外狀況是整合測試和本機實驗。樹外存放區通常會控制用於編譯的 IDDK 版本,以及用於測試的 OS 版本。如果他們想在 NEXT
或 HEAD
中測試功能,就應保持兩者同步。
禁止使用不支援的設定
根據預設,component_manager
會拒絕啟動 ABI 修訂版本戳記表示不受 ABI 相容性保證涵蓋的元件。具體違規事項如下:
- 在特定版本的 Fuchsia 中,只有在
N
自該版本起已支援或淘汰時,才會執行目標 API 級別為N
的元件。 - 特定的 Fuchsia 版本只會執行以
NEXT
或HEAD
為目標的元件,前提是該元件是使用相同版本的 IDK 建構而成。
同樣地,產品組合會拒絕組合與平台不相容的元件。
產品擁有者可以選擇停用這些檢查。舉例來說,即使建構該元件的 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 目標元件,但無法執行使用非 LTS API 的 API 級別 25 目標元件。因此,這兩種元件都需要使用不同的 ABI 修訂版本進行標記,我們可以為每個 (API 級別、LTS 狀態) 組合提供專屬的 ABI 修訂版本,藉此達成這項目標。
我們有這方面的想法,如果決定採用,會在後續 RFC 中說明。
平台元件同時支援所有支援的 API 級別
由於目前沒有任何機制可讓平台元件根據連線另一端的元件 ABI 修訂戳記變更行為,因此支援多個 API 級別意味著同時支援多個 API 級別。平台元件的行為必須符合支援或停用階段的各個 API 級別規格。
更精確地說,平台元件「不得」假設外部元件指定的 API 級別,除非該元件指定的是支援或停用的 API 級別之一。
舉個簡單的例子,如果在 API 級別 15 的 FIDL 通訊協定中移除了方法 Foo
(也就是 Foo
已加上 @available(added=A, removed=15)
註解),但仍支援 API 級別 14,則實作相關通訊協定伺服器的平台元件必須繼續實作 Foo
,直到包含該方法的所有 API 級別都已淘汰為止。
反之,如果該 FIDL 通訊協定伺服器是由樹狀結構外驅動程式庫實作,則與該驅動程式庫通訊的平台元件必須運作,無論驅動程式庫是否實作 Foo
皆然。
這項策略不僅限制了平台元件的實作,也限制了我們對平台介面所做的修改類型。理論上,API 可以任意從一個 API 級別變更為另一個 API 級別,但實際上,如果沒有進一步資訊,我們無法與指定不同 API 級別的外部元件正確通訊,因此有些變更 (例如重複使用 FIDL 通訊協定方法序號) 會導致這種情況。
我們可能會開發不同的策略來支援多個 API 級別,但這項工作會在日後進行。
注意事項
API 和 ABI 相容性保證都受到一些限制。
「保證」的意思
我們「保證」相容性,並不代表 Fuchsia 絕不會違背相容性承諾,因為人非聖賢,難免有錯。也就是說,當我們根據上述條款破壞相容性時,我們會將其視為錯誤。我們會負責在內部解決問題,除了回報錯誤之外,不要求最終開發人員採取任何行動。
讓保固失效
如果終端開發人員「做了一些奇怪的事情」,API 和 ABI 保證就不適用。這包括但不限於:
- 修改 IDK 副本中的檔案。
- 存取內部命名空間的成員
- 手動合成 IDDK 中程式庫要建構的資料
- 將由不同 IDK 建構的共用程式庫連結至單一二進位檔,
- 依此類推
舉例來說,如果您依賴 Fuchsia 中的錯誤行為,就不會算是「做了一些奇怪的事情」。在某些不幸的情況下,修正錯誤可能會被視為「不當行為變更」。如要進一步瞭解相關討論,請參閱「可能引起異議的變更」。
這份 RFC 的範圍不包括全面列出禁止行為。美國最高法院大法官波特史都華特 (Potter Stewart) 在 Jacobellis v. Ohio 一案中曾說過:「我今天不會再試圖進一步定義 [做一些奇怪的事],而且我可能永遠無法成功以明智的方式定義這項行為。但我知道什麼是做一些奇怪的事。」
不當變更
ABI 相容性保證可確保,在支援元件目標 API 級別的 Fuchsia 版本之間,元件不會出現「令人反感的行為變更」。「令人反感」的定義顯然相當主觀,有些人認為有必要的變更,可能會讓其他人反感 (相關 xkcd)。最後,我們會視情況處理不當行為變更的檢舉。
安全性和隱私權
如果發現 Fuchsia 平台介面的某些部分在事後有重大安全性或隱私權問題,我們可能會視需要放棄支援違規的功能,以符合我們的安全性和隱私權目標。
成效
維持與舊版 API 級別的回溯相容性,會造成效能成本。至少,回溯相容的平台二進位檔必須較大,因為會保留更多邏輯。這在某種程度上是不可避免的,但API 級別會以原子化方式淘汰,這可能會加劇問題。
回溯相容性
整份 RFC 都與相容性有關,包括回溯和前向相容性。
測試
測試 API 和 ABI 相容性也是另一個大主題。
Fuchsia 相容性測試 (CTF) 計畫旨在提供測試涵蓋率,以確保我們符合 ABI 相容性保證。目前的涵蓋率偏低,但我們正積極改善這個問題。
目前,我們無法編寫測試來驗證 API 相容性保證;所有樹狀結構內測試都是針對 LEGACY
API 級別建構,因此我們無法複製樹狀結構外客戶針對指定編號 API 級別的體驗。這項問題需要解決,但解決問題不應阻止接受此 RFC。
說明文件
在本 RFC 獲得認可後,其內容將重複使用,做為鎖定 Fuchsia 平台開發人員的多份文件基礎:
- 相容性政策本身。
- API 級別和相容性的指南。
- 文件開頭說明使用指南,指出如何避免我們的相容性保證 (也就是「做一些奇怪的事情」),或許可參考 Abseil 的相容性指南文件。
說明文件也需要更新,以反映現有概念的重新命名。
缺點、替代方案和未知事項
缺點:API 級別是原子
如 RFC-0002 所述,API 級別涵蓋整個 Fuchsia 平台介面。因此,API 級別的階段變更 (例如淘汰 API 級別) 會影響整個 API 級別;我們無法只淘汰部分功能。同樣地,以特定 API 級別為目標的最終開發人員,會將該 API 級別指定給整個 Fuchsia 平台途徑;舉例來說,他們無法將大多數 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 級別先前版本相容 (這類版本不會進行編碼)。查看先前版本的唯一方法是檢查 Git 記錄,但在實際情況中,這並不會發生。
- 由於我們需要能夠從平台中移除功能,因此需要有某些 API 級別支援回溯不相容的變更。這表示 Fuchsia 平台開發人員必須在開發中的 API 級別「之後」對編號 API 級別進行回溯不相容的變更。因此,實際上有兩個正在開發中的 API 級別,Fuchsia 平台開發人員需要對這兩者進行推理。
- 這會使 ABI 修訂作業變得更加複雜。為了在開發中的 API 級別中支援回溯相容性變更,我們需要無限期保留每個版本的 ABI 修訂版本 (每天會建立多個版本)。OS 二進位檔必須支援每個版本的 ABI 修訂版本,其中一個支援的 API 級別為開發中的 API 級別,以及目前里程碑至今的所有版本的 ABI 修訂版本。以目前的發布週期來說,每個 API 級別的 ABI 戳記總數約為 168 個,而根據本文撰寫時的情況,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 的里程碑數字。
替代做法:編號為「in-development」的 API 級別
這份 RFC 的早期草稿更貼近目前實作的平台版本管理模型。在該模型中,NEXT
不存在,而是以可變動的最高編號 API 級別取代,並稱為「開發中」API 級別。
在機械方面,兩個型號之間只有幾個小差異:
- 目前,Fuchsia 平台開發人員會選擇特定 API 級別,以便發布功能。實作此 RFC 後,他們會對
NEXT
進行正式版 API 變更,並自動發布至下一個編號的 API 級別。 - 目前,如果開發人員指定的 API 級別仍在開發中,則在該級別發布後,開發人員會自動改為指定該 API 級別的支援版本。實作此 RFC 後,他們會繼續指定
NEXT
。
這兩項差異都沒有明顯的正面或負面影響。
NEXT
相較於開發中的 API 級別,主要的好處在於可輕鬆進行通訊。這份 RFC 的早期草稿使用了文字遊戲來表達相容性保證:「以支援的 API 級別 N
為目標建構的元件,將可在任何支援的 Fuchsia 版本中成功執行,前提是該版本在支援階段支援 API 級別 N
。」在目前的提案中,所有參與者都會同意特定 API 級別的內容,不需要加上限定條件。
替代做法:不要移除任何內容
我們可以完全禁止不具回溯相容性的變更,讓平台版本管理更簡單。每個 API 級別都會支援先前級別的所有功能,而「平台支援所有 API 級別」屬性會因支援最新 API 級別而「免費提供」。
許多平台 (包括 Windows 和 Android) 都採用了這種做法,但結果是無法清理 API 途徑舊版中的垃圾。
雖然 Fuchsia 平台工程師仍需支援舊版 API 元素 (只要出現在支援或停用的 API 級別),但最終開發人員只需擔心所選目標 API 級別的內容,不需要看到 cruft。
此外,雖然「永不移除」可能會讓版本管理更簡單,但絕對無法完全解決問題。最終開發人員仍需根據所需安裝基礎中最舊的 Fuchsia 平台版本,推斷要指定哪個 API 級別。
-
目前,大多數的下游合作夥伴都依賴 Fuchsia 的測試版,而這類版本每天會產生多次。日後,更多合作夥伴將使用里程碑版本分支的 IDK 和 OS 二進位檔,但我們目前重視這種安排可提供的即時意見回饋。 ↩