RFC-0020:介面序數雜湊 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 我們建議移除程式設計師對介面方法手動指定序數的功能。相反地,編譯器會根據完整方法名稱的雜湊 (即程式庫名稱、介面名稱和方法名稱) 產生序數。 |
作者 | |
提交日期 (年-月-日) | 2018-10-26 |
審查日期 (年-月-日) | 2018-11-29 |
「60% 的時間,也是面試問題的答案」
摘要
我們建議移除程式設計師手動
指定介面方法 1 的序數。
相反地,編譯器會根據
完整方法名稱,即程式庫名稱、介面名稱與種方式
名稱。方法重新命名會透過新的 Selector
屬性與 ABI 相容
(請參閱下文)。
我們特別限制此 FTP 對介面提出序式雜湊 ;不包含列舉、資料表或可延伸聯集。 我們認為這些結構的用途差異在於 需要進一步調查並取得其他 FTP
範例
目前,FIDL 作者會寫入以下內容:
library foo;
interface Science {
1: Hypothesize();
2: Investigate();
3: Explode();
4: Reproduce();
};
這個 FTP 可捨棄序數索引:
interface Science {
Hypothesize(); // look, no ordinals!
Investigate();
Explode();
Reproduce();
};
理論上,編譯器會有效產生像 :
interface Science {
// ordinal = SHA-256 of the fully-qualified method name,
// i.e. "foo.Science/MethodName", truncated to 32 bits
0xf0b6ede8: Hypothesize();
0x1c50e6df: Investigate();
0xff408f25: Explode();
0x0c2a400e: Reproduce();
};
提振精神
- 手動指定序數在很大程度上是機械的。 您不必費心編寫介面 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件
- 如果使用良好的雜湊,雜湊值將不太可能發生 因而改良了人類手動寫字的能力 一般 (使用介面繼承時更是如此)。詳情請參閱 「序樣」一節 瞭解詳情
- 程式設計師必須目前必須確保不同方法的標準
而且不會衝突這個方法適合採用幾種方法的介面,
介面有許多方法,這可能變得相當複雜。
有不同的程式設計風格和學區思維
編號,因此編碼樣式不一致。
- 大部分的介面是從 1 開始到向上的。
- 然而,有些作者偏好將不同的介面方法分組 範圍內 (例如1-10、100-110 等)。
- 移除手動加上編號之序時,也會移除不一致的現象 ,不必讓作者做出決定 要採用哪種樣式
- 介面繼承可能導致異常衝突。
至今已多次嘗試解決問題:
- FTP-010 (已拒絕) 提出了
OrdinalRange
屬性,以便讓 介面 繼承較容易預測因此遭到拒絕 FragileBase
2 是目前的停靠站解決方案, 卻無法解決根本問題,確保負擔並不起 衝突。- 如果序數雜湊,且使用介面和程式庫名稱 計算雜湊值,雜湊序數不會導致 可以解決介面繼承問題 極少數的雜湊衝突)。
- FTP-010 (已拒絕) 提出了
設計
雜湊
雜湊序數衍生自 SHA-256 雜湊:
library name (encoded as UTF-8; no trailing \0)
".", ASCII 0x2e
interface name (encoded as UTF-8; no trailing \0)
"/", ASCII 0x2f
method name (encoded as UTF-8; no trailing \0)
舉例來說,下列 FIDL 宣告:
library foo;
interface Science {
Hypothesize();
Investigate();
Explode();
Reproduce();
};
會使用下列位元組模式來計算序數 雜湊:
foo.Science/Hypothesize
foo.Science/Investigate
foo.Science/Explode
foo.Science/Reproduce
由於 fidlc
已經輸出,因此會使用 .
和 /
分隔符
格式如下的完整方法名稱 (c.f.
fidlc
的 NameName() 方法)。
計算 SHA-256 雜湊後:
- 系統會擷取 SHA-256 雜湊中前 32 位元的內容 (例如:
echo -n foo.Science.Hypothesize | shasum -a 256 | head -c8
) - 上方位元會設為 0,因此可產生有效的 31 位元雜湊 處理 32 位元的零時差值( FIDL 線格式會在 32 位元中保留最重要的位元 ordinal.)
在虛擬程式碼中:
full_hash = sha256(library_name + "." + interface_name + "/" + method_name)
ordinal = full_hash[0] |
full_hash[1] << 8 |
full_hash[2] << 16 |
full_hash[3] << 24;
ordinal &= 0x7fffffff;
選取器屬性重新命名方法
我們定義了供編譯器使用的 Selector
屬性
計算雜湊序數,而非使用方法名稱。
如果方法名稱沒有 Selector
屬性,則該方法
名稱將做為 Selector
。(介面和程式庫)
名稱仍會用於雜湊計算)。
Selector
可用於重新命名方法,而不會破壞 ABI
相容性是手動指定的優點之一
有些奇蹟舉例來說,如要重新命名 Investigate
方法至 Science
介面中的 Experiment
方法,就可以寫入:
interface Science {
[Selector="Investigate"] Experiment();
};
我們僅允許在方法上使用 Selector
屬性。正在重新命名
將程式庫視為罕見,並且維持 ABI 相容性
在此情況下,這不是高優先順序的情況同樣地,
重新命名介面。此外,
含有 Discoverable
屬性的重新命名介面
難懂的是哪個名稱?
序章解決衝突
如果經過雜湊處理的序數導致與其他動物產生衝突或衝突
同一個介面的雜湊序數,編譯器就會發出
因此需要真人為您指定
Selector
屬性
以解決衝突 3。
例如,如果方法名稱 Hypothesize
與
方法名稱 Investigate
,我們可以將 Selector
加入
Hypothesize
,以避免衝突:
interface Science {
[Selector="Hypothesize_"] Hypothesize();
Investigate(); // should no longer conflict with Hypothesize_
};
我們將更新
FIDL API 評分量表
建議附加「_」設為 Selector
的方法名稱
解決衝突。「fidlc
」也會提供這項修正建議。
請注意,每個介面只需要有序數, 與手動指定一般關鍵字類似如果希望普通 各介面的名稱不得重複,且應該在其他介面中提出 FTP。
研究顯示,只要使用 31 位元 介面上有 100 種方法,衝突的機率為 0 .0003% 因此雜湊衝突非常少見
選取器有腳踏車
還有 Selector
的其他建議:
WireName
(abarth
)OriginalName
(ctiller
)Salt
(abarth
;建議新增指定編譯器,因此略有不同) Salt 而不是替代名稱)OrdinalName
我們選擇了 Selector
,因為我們認為這個數字更能反映
屬性的意圖,而不是 WireName 或 OriginalName。
我們選擇讓程式設計師指定序數名稱 有幾個原因:
- 要求索引更為繁瑣,例如複製貼上 原始 SHA-256 雜湊值 (如果發生衝突),
- 指定序數名稱就能啟用與 ABI 相容的方法重新命名, 和
- 指定名稱而非索引 和程式設計師的抽象層級相同 而不會降低一層抽象層 要求學生思考普通
零星體
0 是無效序數,如果
名稱雜湊設為零,編譯器會將其視為雜湊衝突
並要求使用者指定不會經過雜湊處理的 Selector
零時差弱點
我們考慮讓 fidlc
自動重新雜湊名稱,方法是:
但認為:
- 任何這類演算法都是不明顯的
- 零時差情況極為罕見
因此,這種方法並不保證 人體工學和編譯器實作
活動
這個 FTP 也有涵蓋事件,這些事件屬於 方法文件 4。
編譯器與繫結變更
我們認為只須修改 fidlc
就能提供支援
序式雜湊;產生程式碼的後端
已修改。這是因為 fidlc
會計算序數
才會在 JSON IR 中對後端發出。
不需要變更繫結。
執行策略
我們預計在各個階段導入此做法:
- 將程式碼新增至 fidlc 來計算雜湊。
- 為程式庫新增屬性支援。
- 廣播「血糖改變」的意圖,幫助他們瞭解生意 以負載平衡機制分配流量 即可降低應用程式發生效能問題的風險 a.建議手動序數會在特定日期淘汰 就能完成下一步
- 在同一個 CL 中:
a.修改 FIDL 文法的介面方法規則,將序數設為選用;
請參閱下文瞭解詳細資訊。
b.忽略手動指定的序數,並使用雜湊序數做為
傳遞至程式碼產生後端的序數名稱。
c.新增
Selector
,手動修正現有的雜湊衝突 屬性。 - 並在兩週內測試變更,確保沒有正式環境的問題。 a.目前編寫的新 FIDL 介面不應使用一般。 b.手動序數被視為已淘汰,但 fidlc 不會發出 相關警告 c.與團隊合作,確保沒有手動指定的常態作業 存取 API d.請在兩週內更新 FIDL 格式設定工具,以移除 然後大量套用於整個福西亞樹
- 停止支援手動指定物件。
上述是
柔性轉換
變更 fidlc
以使用雜湊序 (步驟 4b) 不應破壞
擲骰子,因為滾動式是以整個樹狀結構的單一版本為基礎。
在 jeremymanson@google.com 實作這個 FTP 中, 他選擇以手動指定的序數,而非雜湊序數 這與上述步驟 4b 不同。這樣就能保留所有現有介面 採用手動指定的標準與 ABI 相容,且僅使用 不指定序數時,就會產生雜湊序數。
人體工學
優點:
- 編寫介面應會較為簡單。
缺點:
- 程式設計師必須瞭解一項新屬性
Selector
, 有兩個用途:重新命名和衝突解決。 - 變更方法名稱未必會破壞 ABI
,不符合程式設計師指定的常態。
使用者教育 (例如更好的說明文件) 可以不容易理解。
- 請注意,其他元件系統,例如 COM 和 Objective-C 通常也會在介面方法執行時中斷 ABI 相容性 已重新命名因此,如果開發人員 也很類似
- 若失去手動控制序數, 在特殊情況下 (例如:會有多個 FIDL 介面 同一個 Zircon 管道上的節目
請注意,本 FTP 作者多半是出於人體工學。
說明文件和範例
我們預計將調整 FIDL 屬性、文法、語言和
線段文件此外,也應更新 API 可讀性評分量表文件
(如 Selector
部分所述)。
回溯相容性
- 雜湊序與手動指定的序數不相容,與 ABI 不相容。
。這應該不是問題
fidlc
變更為二進位 (雜湊的 xor 手動序數都會 值) 和fidlc
是用來建構整個樹狀結構,因此- 樹狀圖的所有部分都會一致採用選定的序數配置。
- 雜湊序與 API (來源) 相容。 現有來源檔案將維持相容。手動基數 已淘汰 (請參閱「導入策略」)。
- 如果兩個不同的 fidlc (即兩個不同的 fidlc) 會發生錯誤 平台來源樹狀結構),以及 FIDL 介面 一種是跨機器通訊的機制作者知道目前未使用 所以這應該不是問題
成效
預計將拖慢至 fidlc
,因為現在必須對所有方法進行雜湊處理
才能計算這些名稱
我們預計對執行階段效能產生輕微的影響。 編譯器可能會針對手動指定的序數產生跳轉表格 這些原本屬於小型的連續範圍,因此將成為二元搜尋 經由稀疏式空間來傳遞雜湊。 相同的機制也可能以不明顯的方式影響二進位檔大小。 (表格導向的調度作業,可能會同時降低其大小和速度方面的疑慮)。
安全性
序式雜湊沒有執行階段,因此不會預期執行階段安全性問題 透過 Wi-Fi 傳送 (例如變更序數值) 變更。
使用加密編譯雜湊 (SHA-256) 可能會導致某些人認為雜湊需求 具備高強度加密功能我們並未認為存在安全性問題,原因是:
- FIDL 編譯器會在編譯時檢查雜湊衝突, 手動解決
- 我們不會使用 SHA-256 進行加密編譯,但我們需要雜湊資料 不太可能引發衝突。 CRC-32 (甚至是 strlen()) 也能運作,但可能會產生更多 但這樣就可能會造成不便。
截斷 SHA-256 雜湊可能也會有疑慮,但再次提醒 認為存在安全性問題,因為 FIDL 編譯器會以靜態方式檢查 雜湊衝突 5。
測試
ianloic@google.com 分析了現有的 FIDL 介面,並判定 表示雜湊衝突沒有錯誤
我們會審慎考量如何測試雜湊衝突的實際情況 在設計上,以人為方式產生雜湊衝突並不容易 (在設計上)。
否則,就電池單元測試 CQ 測試 相容性測試 手動測試應已足夠,確保序數雜湊是穩健的
缺點、替代方案和未知
這個 FTP 只會為介面處理序數雜湊。 它不會提議變更列舉的手動列舉序數 或可延伸聯集
jeffbrown@google.com 建議進行完美雜湊,當時我們考慮這麼做。 FTP 作者不熟悉完美的雜湊處理方式,不過相信 日後如果增加額外方法,現有 YAML 檔案 方法,因而破壞 ABI 的相容性,使得完美的雜湊值不適合我們。 動態完美雜湊或許可行,但同樣與 搜尋度也較不常見,也比標準格式更複雜 而不需要進一步調查。
另一種移除手動序數的方法,是傳送完整的方法名稱。 大多數 (大部分?) 其他遠端程序呼叫 (RPC) 系統都支援連線,請參閱 參考資料)。這會對執行階段效能造成影響 可能會與 FIDL 的預定用途發生衝突。
我們考慮指定使用的雜湊值,方便日後變更
萬一 SHA-256 最後發生其他雜湊能夠解決的問題,
這項設計很常見於安全性應用,在其廣泛使用的加密編譯中
雜湊值之後會發現安全漏洞。
不過,指定雜湊碼可能需要變更傳輸格式
且需要所有語言繫結都導入程式碼來選取雜湊演算法。
這會大幅簡化編譯器和繫結程式碼。
我們認為,不必在那之前做出取捨。
我們瞭解
git
也採用 SHA-1 態度,
現在還可用來追蹤決策進度,但我們認為
幾度差異,到適合以硬式編碼方式寫入雜湊演算法。
探索
- 利用節省空間的方式找出方法,
方法的第一類別表示法,使方法成為第一類別
- 例如啟用可在 FIDL 呼叫中用做引數的方法,或者 FIDL 方法則是傳回其他方法。 目前已有適用的用途,方法會傳回 具有單一方法的介面,做為傳回實際方法的 Proxy。
- 建議的 31 位元雜湊值可擴展至64/128/53 位元; SHA-256 提供大量 Obit。
- 將
ordinal
重新命名為selector
,這是提供相同服務的現有概念 用於其他語言和元件系統 - 建議您區分方法名稱和介面名稱,因此我們 包含兩項不同的資料 此 ID 可明確參照介面名稱,且可以明確參照方法名稱。 為此,我們可能需要超過 32 位元。
- 如上所述,列舉、資料表和可延伸聯集不在範圍內。
即便如此,我們仍認為這種 FTP 可能適用於他們。
初步想法:
- 我們無法確定列舉項目是否需要此功能。 更簡單且標準化的連續整數編號似乎已足夠。
- 這可能直接套用至可延伸聯集。
- 表格需要不同的線路格式才能採用序式雜湊,因為 普通
- FIDL 目前會保留序數上限,並在文件中明確指出
部分上限位元適用於控制流程等。
作者認為其中一項原因也可能是牽涉到
與一般狀況產生衝突
要複習嗎?
- 將序言展開至 64 位元 (如上文所述) 可大幅解決 而負責任的 AI 技術做法 有助於達成這項目標
abarth@google.com
建議在 Fuchsia IPC 聊天室中預訂,以便僅預訂0xFFFFxxxx
。
- 我們可以將方法的引數類型加入計算後的雜湊值中
因為我們日後需要支援超載方法。
- jeffbrown@google.com 提到,雜湊處理完整方法簽章可能會受到限制 介面擴充功能,導致地圖超載 預計投入大量的程式設計語言
- 由於序數雜湊應會在介面繼承時解決一般衝突問題
FragileBase
屬性也可以移除。- 程式碼搜尋顯示約 9 次使用
FragileBase
。
- 程式碼搜尋顯示約 9 次使用
- 作者擔心介面有大幅進化的現象
如果許多方法都含有
Selector
屬性,這些方法會越來越難查看。- 解決這個問題的一種方法是採用類似於 Objective-C 類別 或 C# 部分類別。 原已宣告的介面可以「擴充」具備屬性 新增至另一個宣告中。
既有藝術品和參考資料
有趣的是,我們並不知道 使用方法名稱的雜湊來識別要呼叫的方法。
大多數 RPC 系統會依名稱呼叫方法 (例如 gRPC/Protobuf 服務、Thrift、D-Bus)。 針對處理中的方法呼叫,Objective-C 會使用保證專屬字元* 指標 ,用來識別應在類別呼叫的方法。 Objective-C 執行階段可以將選取器對應至字串化方法名稱,反之亦然。 如果是獨立程序的方法呼叫,Objective-C 分散式物件會使用 方法 叫用名稱。 COM 會直接使用 C++ vtable 進行處理中的呼叫,因此取決於 ,以支援方法分派作業。 apang@google.com 建議 ctiller@google.com 中資料表的序數雜湊 提供提案。ianloic@google.com 和 apang@google.com 於 2018 年 10 月 18 日週四與 我在這裡
-
Mojo/FIDL1 也並未要求程式設計師指定序數; 而是依序產生 (類似 FlatBuffers 的 資料表欄位的隱含標記編號)。 ↩
-
您之前可以建立從 任何其他 FIDL 介面 不過,介面和超介面會使用相同的序數空間 因此如果您將方法新增至介面 子介面。 為瞭解決 繼承 / 序衝突問題,但直到我們找出 想要解決這個問題,我們已將介面的預設選項切換為 。 使用者仍然可以在介面上,
[FragileBase]
屬性。 如果遇到這個問題,編譯器應顯示錯誤訊息 以簡要說明 我 (abarth@google.com) 新增了[FragileBase]
屬性 「平台來源樹狀結構」中使用 FIDL 介面繼承的每個位置 (希望您!) 如有任何疑問或遇到任何問題,歡迎與我們聯絡。 --abarth@google.com ↩ -
我們不認為有充分的口頭衝突需要擔保 自動增加任何額外導入作業及認知到複雜程度 衝突解決我們可以回頭審視這項決策而不中斷 如果資料顯示序曲衝突 問題。 ↩
-
如果只宣告結果,此方法會稱為事件。 然後再定義來自伺服器的垃圾郵件。 ↩
-
jln@google.com Write, "是可以截斷 SHA-2 而沒有, 所以你可以在不被截斷的地方使用 ↩