適用地區

若要選取哪些功能放入其 命名空間 中,元件在其 清單 中為每個功能指定一個 use 宣告。不過,由於功能路徑涉及一連串的元件,因此即使元件 use 是能力,也不代表該功能一律可用。可能原因包括:鏈結中的某個元件未將能力路徑傳送至下一個元件,或是某個元件無法解析。

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

選項

架構支援 availability 的下列選項:

必填

最常用的 availability 選項是 required,表示元件一律需要這項能力,如果沒有這項功能,元件就無法正常運作。如果未指定供應情形,系統會自動設定這個預設選項。

選用

optional 表示某些設定可能不具備這項能力。如果元件 use 是選用能力,但結果無法使用,元件應能正常運作,例如停用需要該能力的所有功能。

不過,如果某些設定無法使用 optional 能力,架構會預期拓撲仍包含能力完整的路徑,並在 void 中終止。這樣一來,產品擁有者就必須明確選擇能力是否可用 (路徑會在某個供應商元件終止),或功能是否不可用 (路徑會在 void 終止)。如果路徑不完整,工具和診斷會將此回報為錯誤。

過渡期

transitional 就像是 optional 的弱化版。與 optional 類似,如果元件使用 transitional 能力,就應容許缺少該能力。不過,與 optional 不同的是,transitional 路由不需要在 void 中終止,如果 transitional 路由不完整或無效,工具和診斷不會回報任何錯誤。

「transitional」這個名稱表示這個選項適用於柔和的轉場效果。舉例來說,假設您有 Echo 通訊協定,想要替換為 EchoV2。在轉換過程的早期階段,您可以將用戶端變更為使用新通訊協定,並提供 transitional 支援。use稍後,一旦建立端對端路徑,您就可以將供應情形升級為 requiredoptional。如果您嘗試使用 optional工具和診斷會回報用戶端元件的父項缺少 Echo2 的能力路徑,而 transitional 則會抑制這類警告。

與目標相同

same_as_target 會做為傳遞路徑:這會導致可用性從路徑目標元件設定的任何可用性繼承。這對於傳遞大量功能的的中介元件很有用,因此當目標中的路徑 availability 變更時,來源不需要變更。

因為 use 是能力的最終目的地,所以 same_as_target 不適合做為 use 的選項。

可用性比較

可用性選項之間有相對「強度」順序。 由高至低的順序為:required > optional > transientsame_as_target 不屬於此類,因為它是直通路線:same_as_target 能力路線的強度實際上等於從目標繼承的任何可用性。

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

工具和診斷

設定可用性的主要影響是控管主機工具和診斷報告如何回報轉送錯誤。簡單來說,這表示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 墓誌銘關閉。

source_availability: unknown

cml 還有額外功能,可根據是否包含具有來源子項宣告的 cml 分片,自動產生 requiredoptional void offer。如要進一步瞭解這項功能,請參閱建構文件

target_availability: unknown

cml 還有一個額外功能,可根據是否包含具有目標子項宣告的 cml 分片,用來省略 offer。如要進一步瞭解這項功能,請參閱建構文件

範例

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

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

  • echo_client,會嘗試使用 echo_server 提供的各種通訊協定
  • echo_server,其中提供一些通訊協定
  • echo_realm,是 echo_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,但都是完整的,且會在實際元件中終止。
    • 每條路線的來源和目標之間的可用性都通過比較檢查
  • 由於所有路徑都會完成,因此工具和診斷程序不會記錄錯誤。