適用地區

如要選取要放入其資訊清單的每項功能的 use 宣告,元件會指定這些功能。不過,由於功能路由涉及一連串的元件,因此即使元件 use 為某項能力,也不代表該功能一律可用。可能會因為各種原因而無法使用,例如鏈結中其中一個元件未將能力重新導向,或是其中一個元件無法解析。

當元件 use 或路由能力時,可能會對能力是否必須可用有所期待。在某些情況下,某項能力對元件的運作至關重要:如果有人建立的拓樸無法將能力路由至元件,則應盡早偵測這項失敗情形,以免發生錯誤。不過,在其他情況下,元件可能會容許缺少這項能力,或者在特定設定中,這項能力可能會缺席。為了因應這些不同情況,cmluseofferexpose 上提供 availability 選項,元件可使用該選項宣告對能力可用性的預期。

選項

此架構支援 availability 的下列選項:

必要

最常用的 availability 選項是 required,表示元件一律會預期該能力可用,且如果該功能缺少,則無法正常運作。如果未指定可用性,系統會自動設定這個預設選項。

選用

optional 表示某些設定可能不提供某項能力。如果元件 use 的選用能力無法使用,該元件應可在沒有該功能的情況下運作,例如停用需要該能力的任何功能。

不過,如果某些設定無法使用 optional 能力,架構會預期拓撲仍包含以 void 結尾的能力完整路徑。如此一來,產品擁有者就能明確選擇是否要提供該能力 (路徑會在某個提供者元件中終止),或是不提供 (路徑會在 void 中終止)。如果路徑不完整,工具和診斷程序就會將其回報為錯誤。

新舊混搭風

transitional 就像是 optional 的弱版本。如同 optional,如果元件使用 transitional 能力,則應能容許缺少這項能力。不過,transitional 路徑不像 optional 需要在 void 中結尾,如果 transitional 路徑不完整或無效,工具和診斷程序就不會回報任何錯誤。

「transitional」這個名稱暗示這個選項可用於軟性轉場。舉例來說,假設您有一個 Echo 通訊協定,想要替換為 EchoV2。在這個轉換作業的早期步驟中,您可以變更用戶端,以便在 transitional 可用時使用新通訊協定。use日後建立端對端路徑後,您可以將可用性升級為 requiredoptional。如果您改為嘗試使用 optional工具和診斷程序會指出用戶端元件的父項缺少 Echo2 的能力路徑,而 transitional 會抑制這類警告。

與目標相同

same_as_target 會做為傳遞作業:讓可用性從路徑目標元件設定的可用性繼承。這對於傳遞大量功能的中介元件而言非常實用,因為在目標中變更路徑的 availability 時,來源就不需要變更。

use 的最終目的地是 use 能力,因此 same_as_target 不是 use 的有效選項。

可用性比較

可用選項之間有相對的「強度」排序。從最強到最弱的順序如下:required > optional > transientsame_as_target 不是這項功能的一部分,因為它是傳遞功能:same_as_target 能力路徑的強度實際上等同於從目標繼承的任何可用性。

在許多情況下,從來源降級至目標的供應情形是有效且實用的做法。舉例來說,如果元件 XY 公開 required 能力,Y 可以選擇將能力 use 設為 optional,或將能力 offer 設為另一個子項的 optional。不過,如果要升級來源的可用性,就會發生路由錯誤。發生這種情況時,任何嘗試使用或轉送能力動作都會失敗,就像轉送鏈結不完整時會失敗一樣。這是錯誤,因為這表示您嘗試建立的供應情形保證條件,比來源保證的更嚴格。舉例來說,如果父項元件將能力 offeroptional,那麼元件將能力 userequired 就沒有意義,因為這表示父項已宣告能力可能無法使用。

工具和診斷

設定可用性的最大影響,就是控制主機工具和診斷報告如何回報轉送錯誤。簡而言之,availability 越弱,就越不嚴格。以下是詳細規格:

  • 如果 required 能力路徑不完整、無效或結尾為 void
    • Scrutiny 會將這項問題回報為路徑錯誤。如果建構設定要求通過此測試,這會導致建構錯誤。
    • component_manager 會在使用元件的範圍中記錄 WARNING 訊息,說明路由錯誤。
  • 如果 optional 能力路徑不完整或無效:
    • Scrutiny 會將這項問題回報為路徑錯誤。如果建構設定要求通過此測試,這會導致建構錯誤。
    • component_manager 會在使用元件的範圍中記錄 INFO 訊息,說明路由錯誤。
  • 如果 optional 能力路徑結尾為 void
    • 嚴格審查不會回報錯誤。
    • component_manager 可能會記錄 INFO 訊息,但不會記錄錯誤。
  • 如果 transitional 能力路徑不完整、無效或結尾為 void
    • 系統不會記錄錯誤或其他資訊。

對於一般執行階段行為,availability 不會產生任何影響。舉例來說,假設元件嘗試 use 其命名空間中路徑中斷的通訊協定。如果通訊協定以 requiredoptional 進行路由,最終結果會相同:

  • 該通訊協定會顯示在元件的命名空間中。
  • 連線至能力的初始呼叫會成功 (假設使用標準單向 API,例如在 rust 中使用 connect_to_protocol)。
  • component_manager 會嘗試轉送能力。最後,轉送作業會失敗,管道會關閉並顯示 NOT_FOUND epitaph

source_availability: unknown

cml 具有額外功能,可用於自動產生 requiredoptional void offer,具體取決於是否包含 cml 區塊,該區塊包含來源的子宣告。如要進一步瞭解這項功能,請參閱建構文件

範例

以下範例說明本文件中所述的概念。

在這個範例中,有三個元件:

  • echo_client,會嘗試使用 echo_server 提供的各種通訊協定
  • echo_server,提供一些通訊協定
  • echo_realmecho_clientecho_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.EchoV2fuchsia.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.Echofuchsia.example.EchoV2fuchsia.example.Stats
    • 每個路徑雖然有不同的 availability,但都會完成並在實際元件中終止。
    • 每條路線的來源和目標之間的可用性都通過比較檢查
  • 工具和診斷工具不會記錄錯誤,因為所有路徑都已完成。