use
不過,由於功能轉送涉及元件鏈,只是因為元件 use
的能力並不代表隨時都能使用。無法使用的原因有很多,例如鏈結中的某個元件未轉送能力,或是其中一個元件無法解析。
當元件 use
或轉送能力時,對於是否能夠使用該能力,它可能會有不同的預期目標。在某些情況下,能力是元件作業的關鍵所在:如果使用者建立的拓撲就是無法將能力轉送至元件,最好能盡早偵測失敗情況以防發生錯誤。但在其他情況下,元件可能會容許能力缺少功能,或者某些設定可能會缺少能力。為因應這些不同情境,cml 會在 use
、offer
和 expose
上提供 availability
選項,讓元件可用來宣告自身對於能力可用性的預期。
選項
此架構支援下列 availability
選項:
必要
最常用的 availability
選項為 required
,表示元件一律預期可使用該能力,如果沒有,就無法預期可正常運作。這是預設選項,在未指定可用性的情況下會自動設定。
選用
optional
代表某些設定可能無法提供特定能力。如果元件 use
為無法使用的選用能力,該元件應能在沒有該功能的情況下正常運作,例如透過停用任何需要該能力的功能。
然而,如果某些設定不支援 optional
能力,架構會預期拓撲仍包含終止 void
的能力的完整路徑。如此一來,產品擁有者應明確選擇該能力是否可用 (其路徑會在某些供應商元件終止) 或不存在 (路徑會於 void
終止)。如果路徑不完整,工具與診斷會回報此錯誤。
過渡
transitional
似乎是較弱的 optional
版本。和 optional
一樣,如果元件使用 transitional
能力,就應容許沒有這項能力。不過,與 optional
不同的是,transitional
路徑不需要在 void
中終止,而且如果 transitional
路徑不完整或無效,工具和診斷就不會回報任何錯誤。
「轉換」名稱意味著這個選項適用於非流暢轉換。例如,假設您有一個 Echo
通訊協定,並且想要替換為 EchoV2
。在轉換初期,您可以將用戶端變更為 use
新的通訊協定,並使用 transitional
可用性。建立端對端路徑之後,您可以將可用性升級至 required
或 optional
。如果您嘗試改用 optional
,工具與診斷工具會說明用戶端元件的父項缺少 Echo2
的能力路徑,而 transitional
則會隱藏這類警告。
與目標相同
same_as_target
可做為直通式,會從路徑目標元件設定的供應情形沿用。這對於通過大量功能的中繼元件而言非常實用,因此當路徑的 availability
在目標中發生變更時,無需在來源中變更。
由於 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
:- Scrutiny 不會回報錯誤。
component_manager
可能會記錄INFO
訊息,但不會記錄任何錯誤。
- 如果
transitional
能力路徑不完整、無效,或在void
中結束:- 系統不會記錄錯誤或其他資訊。
對於一般執行階段行為,availability
沒有任何作用。舉例來說,假設元件嘗試對命名空間中的通訊協定 use
,而其路徑已中斷。將通訊協定轉送為 required
或 optional
時,最終結果會相同:
- 通訊協定會顯示在元件的命名空間中。
- 連線至該能力的初始呼叫會成功 (假設標準單向 API 使用類似於 Rust 中的 connect_to_protocol)。
component_manager
會嘗試轉送能力。最終的轉送作業會失敗,而管道也會以NOT_FOUND
劇集關閉。
source_availability:不明
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
時,都會在實際元件中完成並終止。 - 在每個路徑中,來源和目標之間的可用性通過比較檢查
- 當每個路徑都有不同的
- 由於所有路線均已完成,工具和診斷不會記錄錯誤。