如要選取要放入其資訊清單的每項功能的 use
宣告,元件會指定這些功能。不過,由於功能路由涉及一連串的元件,因此即使元件 use
為某項能力,也不代表該功能一律可用。可能會因為各種原因而無法使用,例如鏈結中其中一個元件未將能力重新導向,或是其中一個元件無法解析。
當元件 use
或路由能力時,可能會對能力是否必須可用有所期待。在某些情況下,某項能力對元件的運作至關重要:如果有人建立的拓樸無法將能力路由至元件,則應盡早偵測這項失敗情形,以免發生錯誤。不過,在其他情況下,元件可能會容許缺少這項能力,或者在特定設定中,這項能力可能會缺席。為了因應這些不同情況,cml 在 use
、offer
和 expose
上提供 availability
選項,元件可使用該選項宣告對能力可用性的預期。
選項
此架構支援 availability
的下列選項:
必要
最常用的 availability
選項是 required
,表示元件一律會預期該能力可用,且如果該功能缺少,則無法正常運作。如果未指定可用性,系統會自動設定這個預設選項。
選用
optional
表示某些設定可能不提供某項能力。如果元件 use
的選用能力無法使用,該元件應可在沒有該功能的情況下運作,例如停用需要該能力的任何功能。
不過,如果某些設定無法使用 optional
能力,架構會預期拓撲仍包含以 void
結尾的能力完整路徑。如此一來,產品擁有者就能明確選擇是否要提供該能力 (路徑會在某個提供者元件中終止),或是不提供 (路徑會在 void
中終止)。如果路徑不完整,工具和診斷程序就會將其回報為錯誤。
新舊混搭風
transitional
就像是 optional
的弱版本。如同 optional
,如果元件使用 transitional
能力,則應能容許缺少這項能力。不過,transitional
路徑不像 optional
需要在 void
中結尾,如果 transitional
路徑不完整或無效,工具和診斷程序就不會回報任何錯誤。
「transitional」這個名稱暗示這個選項可用於軟性轉場。舉例來說,假設您有一個 Echo
通訊協定,想要替換為 EchoV2
。在這個轉換作業的早期步驟中,您可以變更用戶端,以便在 transitional
可用時使用新通訊協定。use
日後建立端對端路徑後,您可以將可用性升級為 required
或 optional
。如果您改為嘗試使用 optional
,工具和診斷程序會指出用戶端元件的父項缺少 Echo2
的能力路徑,而 transitional
會抑制這類警告。
與目標相同
same_as_target
會做為傳遞作業:讓可用性從路徑目標元件設定的可用性繼承。這對於傳遞大量功能的中介元件而言非常實用,因為在目標中變更路徑的 availability
時,來源就不需要變更。
use
的最終目的地是 use
能力,因此 same_as_target
不是 use
的有效選項。
可用性比較
可用選項之間有相對的「強度」排序。從最強到最弱的順序如下:required > optional > transient
。same_as_target
不是這項功能的一部分,因為它是傳遞功能:same_as_target
能力路徑的強度實際上等同於從目標繼承的任何可用性。
在許多情況下,從來源降級至目標的供應情形是有效且實用的做法。舉例來說,如果元件 X
向 Y
公開 required
能力,Y
可以選擇將能力 use
設為 optional
,或將能力 offer
設為另一個子項的 optional
。不過,如果要升級來源的可用性,就會發生路由錯誤。發生這種情況時,任何嘗試使用或轉送能力動作都會失敗,就像轉送鏈結不完整時會失敗一樣。這是錯誤,因為這表示您嘗試建立的供應情形保證條件,比來源保證的更嚴格。舉例來說,如果父項元件將能力 offer
為 optional
,那麼元件將能力 use
為 required
就沒有意義,因為這表示父項已宣告能力可能無法使用。
工具和診斷
設定可用性的最大影響,就是控制主機工具和診斷報告如何回報轉送錯誤。簡而言之,availability
越弱,就越不嚴格。以下是詳細規格:
- 如果
required
能力路徑不完整、無效或結尾為void
:- Scrutiny 會將這項問題回報為路徑錯誤。如果建構設定要求通過此測試,這會導致建構錯誤。
component_manager
會在使用元件的範圍中記錄WARNING
訊息,說明路由錯誤。
- 如果
optional
能力路徑不完整或無效:- Scrutiny 會將這項問題回報為路徑錯誤。如果建構設定要求通過此測試,這會導致建構錯誤。
component_manager
會在使用元件的範圍中記錄INFO
訊息,說明路由錯誤。
- 如果
optional
能力路徑結尾為void
:- 嚴格審查不會回報錯誤。
component_manager
可能會記錄INFO
訊息,但不會記錄錯誤。
- 如果
transitional
能力路徑不完整、無效或結尾為void
:- 系統不會記錄錯誤或其他資訊。
對於一般執行階段行為,availability
不會產生任何影響。舉例來說,假設元件嘗試 use
其命名空間中路徑中斷的通訊協定。如果通訊協定以 required
或 optional
進行路由,最終結果會相同:
- 該通訊協定會顯示在元件的命名空間中。
- 連線至能力的初始呼叫會成功 (假設使用標準單向 API,例如在 rust 中使用 connect_to_protocol)。
component_manager
會嘗試轉送能力。最後,轉送作業會失敗,管道會關閉並顯示NOT_FOUND
epitaph。
source_availability: unknown
cml 具有額外功能,可用於自動產生 required
或 optional void
offer
,具體取決於是否包含 cml 區塊,該區塊包含來源的子宣告。如要進一步瞭解這項功能,請參閱建構文件。
範例
以下範例說明本文件中所述的概念。
在這個範例中,有三個元件:
echo_client
,會嘗試使用echo_server
提供的各種通訊協定echo_server
,提供一些通訊協定echo_realm
:echo_client
和echo_server
的父項,用於連結兩者
我們來看看他們的 cml 檔案:
// echo_client.cml
{
...
use: [
{ protocol: "fuchsia.example.Echo" },
{
protocol: "fuchsia.example.EchoV2",
availability: "transitional",
},
{
protocol: "fuchsia.example.Stats",
availability: "optional",
},
],
}
// echo_server.cml
{
...
capabilities: [
{ protocol: "fuchsia.example.Echo" },
],
expose: [
{
protocol: "fuchsia.example.Echo",
from: "self",
},
],
}
// echo_realm.cml
{
offer: [
{
protocol: "fuchsia.example.Echo",
from: "#echo_server",
to: "#echo_client",
availability: "required",
},
{
protocol: "fuchsia.example.Stats",
from: "void",
to: "#echo_client",
availability: "optional",
},
],
children: [
{
name: "echo_server",
url: "echo_server#meta/echo_server.cm",
},
{
name: "echo_client",
url: "echo_client#meta/echo_client.cm",
},
],
}
請注意,如果省略 availability
,系統會預設為 required
。使用這個拓樸結構時,行為如下:
echo_client
將可成功連線至fuchsia.example.Echo
。echo_client
將無法連線至fuchsia.example.EchoV2
或fuchsia.example.Stats
。- 工具和診斷功能不會記錄錯誤。
fuchsia.example.Stats
沒有錯誤,因為它是optional
,且會導向void
。fuchsia.example.Stats
沒有錯誤,因為它是transient
。
接著,我們來看看其他版本的情況:
// echo_client.cml
{
...
use: [
{ protocol: "fuchsia.example.Echo" },
{
protocol: "fuchsia.example.EchoV2",
availability: "transitional",
},
{
protocol: "fuchsia.example.Stats",
availability: "optional",
},
],
}
// echo_server.cml
{
...
capabilities: [
{
protocol: [
"fuchsia.example.Echo",
"fuchsia.example.EchoV2",
"fuchsia.example.Stats",
],
},
],
expose: [
{
protocol: [
"fuchsia.example.Echo",
"fuchsia.example.EchoV2",
],
from: "self",
},
{
protocol: "fuchsia.example.Stats",
from: "self",
availability: "optional",
},
],
}
// echo_realm.cml
{
offer: [
{
protocol: [
"fuchsia.example.Echo",
"fuchsia.example.EchoV2",
],
from: "#echo_server",
to: "#echo_client",
availability: "same_as_target",
},
{
protocol: "fuchsia.example.Stats",
from: "#echo_server",
to: "#echo_client",
availability: "optional",
},
],
children: [
{
name: "echo_server",
url: "echo_server#meta/echo_server.cm",
},
{
name: "echo_client",
url: "echo_client#meta/echo_client.cm",
},
],
}
現況:
echo_client
將可成功連線至fuchsia.example.Echo
、fuchsia.example.EchoV2
和fuchsia.example.Stats
。- 每個路徑雖然有不同的
availability
,但都會完成並在實際元件中終止。 - 每條路線的來源和目標之間的可用性都通過比較檢查
- 每個路徑雖然有不同的
- 工具和診斷工具不會記錄錯誤,因為所有路徑都已完成。