RFC-0121:元件生命週期事件

RFC-0121:元件生命週期事件
狀態已接受
領域
  • 元件架構
說明

此 RFC 將元件架構事件功能正式化。

問題
毛皮變化
作者
審查人員
提交日期 (年-月-日)2021-05-26
審查日期 (年-月-日)2021-08-11

摘要

這份文件記錄了設計研議、原則及決策 關於元件事件:概念、資訊清單語法和 FIDL 通訊協定。

以下其中一項決策是在 2020 年初並實施。 提出了其他幾項概念 以及早期決策建議將許多功能加入許可清單 但我們正在設法遷移至 更健全的機制

本文件的範圍涵蓋下列 Component Framework API:

  • CML:編寫元件資訊清單的語言
  • fuchsia.sys2/events.fidl:目前的 API 介面,其中元件事件 FIDL API 有效目標是將所有事件 API 升級至 fuchsia.component/events.fidl,並可在 SDK 中使用。

提振精神

元件管理員會在內部處理元件的生命週期,但不會公開 將資訊傳給元件某些特殊權限的用戶端 (例如: 診斷、測試、元件監督、偵錯工具) 需要更深入的分析 轉換為元件生命週期

導入元件事件,是將這類資訊公開給 具有特殊權限的元件這些事件都會由元件分派 元件執行個體的生命週期轉換作業時。 能力轉送 API 在一些稱為 本文件介紹更多設計方式,讓元件能夠公開及提供 事件本身

設計

本節概述元件事件目前與 API 的設計 強調目前設計不適合長期執行的 並指出日後可以設計和實作的功能。

元件事件串流功能

元件事件會被模擬為「事件串流」即便沒有技術背景,也能因這些工具的功能而受益每個事件 串流能力是指單一元件或元件的子樹狀結構 許多新概念撰寫本文件時,系統會將事件視為 個別事件功能 (非事件串流)。元件管理員 在生命週期轉換時,代表元件發出事件 會發生什麼事

如同所有能力,事件串流也可以轉送。事件串流處於以下狀態時:

  • 從架構公開/提供:事件是指 公開或提供活動

  • 從父項/子項使用:元件可以監聽轉送至該事件的事件 子或向上層發布商移動元件的父項可以直接 在沒有子項明確的情況下,使用來自子項的生命週期事件串流 從架構中公開事件

上述根層級的事件串流

事件串流可由「父項」的根領域使用/提供。個人中心 您可能會好奇 決定拓撲的根源?元件管理員術語說明 對於元件管理員提供的根領域資訊 「高於根層級」。

「高於根層級」的事件串流專屬於根領域 整個元件執行個體拓撲這些事件串流的範圍可以限定為 並在路徑轉送時參照拓撲的子樹狀結構。您可以在 類似整體或 Cloud Storage 目錄功能轉送方式 子目錄 (目錄轉送宣告中的 subdir 鍵)。 如要監聽範圍限定於整個領域的事件,您必須具有 源自於可用根目錄的限定範圍事件串流能力。活動 隱瞞整個領域,具有特殊權限/敏感性並破壞封裝 因此,我們明確從上述根層級 透過靜態轉送控管存取權

請參考以下範例:

以下顯示宣告的樹狀結構

// root.cml
{
  offer: [
    {
      event_stream: "started",
      from: "parent",
      to: "#core",
      scope: "#core"
    },
  ]
}

// core.cml
{
  offer: [
    {
      event_stream: "started",
      from: "parent",
      to: "#test_manager",
      scope: "#test_manager"
    },
  ]
}

// test_manager.cml
{
  offer: [
    {
      event_stream: "started",
      from: "parent",
      to: [ "#archivist", "#tests" ]
      scope: "#tests",
    }
  ]
}

// tests.cml
{
  offer: [
    {
      event_stream: "started",
      from: "parent",
      to: [ "#test-12345" ]
      scope: "#test-12345",
    }
  ]
}

// test-12345.cml
{
  offer: [
    {
      event_stream: "started",
      from: "framework",
      scope: "#bar",
      to: "#foo"
    }
  ],
  use: [
    {
      event_stream: "started",
      from: "parent"
    },
    {
      event_stream: "stopped",
      from: "framework",
      scope: "#bar",
    }
  ]
}

// foo.cml
{
  use: [
    {
      event_stream: "started",
      from: "parent"
    }
  ]
}

// archivist.cml
{
  use: [
    {
      event_stream: "started",
      from: "parent",
    }
  ]
}

在這個例子中:

  • foo 收到 started 事件時,test-12345 可將 bar 轉送至該事件 基礎架構

  • archivist」可取得 tests 下所有元件的 started 事件 因為有 startedtest_manager 提供 coreroot取得,但來自 above root, 一向縮減範圍

  • test-12345 是測試根目錄,可啟動事件中所有位於 就和 archivist 一樣。不過,與考古學家不同 (可取得 tests 的所有事件),其本身只能取得與以下項目相關的事件: 測試,因為 tests 將事件範圍限定為 test-12345

這個範例顯示了目前事件的其中一個核心用途。 封存學家能觀察每項測試在獨立測試中的變化 。此外,每項測試都能取得測試中所有元件的事件,或 特定節目

合併事件串流

同類型的事件串流可以合併為單一串流。 舉例來說,在上述範例中,#test-12345 可提供 stoppedfoobar 套用至其他元件做為單一能力。該元件 就會同時取得 foobarstopped 事件。

// core.cml
offer: [
  {
    event_stream: "stopped",
    from: [ "#netstack", "#supervisor" ],
    to: "#someone",
  }
]

目前系統不允許顯示/提供自己的活動。不過 這裡還有成長空間,允許活動公開/提供自訂事件 調度資源

事件模式

撰寫這份文件時,系統可能會以非同步的方式擷取事件 或是使用同步方式意圖「只」具有非同步事件,並淘汰該事件 以及完整的同步處理活動

同步取用事件可讓訂閱者封鎖元件 來處理事件,然後繼續。這種測試方式 也考慮到偵錯工具

在那之後,我們已瞭解到,可使用同步處理事件來編寫測試時可以使用 非同步事件因此 工作 會完全清除同步處理事件,不過元件中仍有一些用途 經理內部測試。認為同步處理事件會有幫助 導入偵錯工具 (例如步驟或 zxdb),但現在我們會開發解決方案 可準確符合偵錯工具的需求

提案是將使用同步處理事件的測試加入許可清單,並用於 完全清除同步處理事件。

事件類型

撰寫本文件時,系統會分為兩種事件類別:

  • 生命週期事件。這些事件會反映 元件執行個體的生命週期,並發出該值 而元件管理工具則負責管理此類資訊
  • 已淘汰的事件。這些事件不會反映 目前我們會設法完全移除這些元件執行個體 提供更適當的解決方案

可用的生命週期事件類型如下:

  • Discovered:這是元件生命週期的第一個階段。 在建立動態子項時分派給靜態子項 父項解析時間,以及元件管理員的根層級 就可以開始
  • Resolved:執行個體的宣告已成功解析為 讓應用程式從可以最快做出回應的位置 回應使用者要求
  • Started:這個執行個體已根據元件管理員啟動。 但如果這是可執行元件,執行器就會進一步 就能啟動元件元件已開始執行 可能尚未開始執行程式碼
  • Stopped:已成功停止執行個體。這個事件的發生時間早於 已刪除。
  • Destroyed:開始刪除執行個體。已重新啟動執行個體 阻止了執行個體仍存在於父項的領域中,但 。
  • Purged:已成功刪除執行個體。執行個體已停止 並不再存在於父項的領域中

以及下列已淘汰的事件類型:

  • Running:這個事件是由元件管理員合成,適用於所有使用者 訂閱當下正在運作的元件這項活動 衍生自 started,但適用於啟動 (且未停止) 的元件 事件。最後,渴望得到 Component Framework Query API 來瞭解執行中的項目因此, 計畫是將這個事件加入許可清單,供其唯一的客戶 (Archivist) 和 ,請使用新的 API 並移除 running

  • Capability Routed:此事件是為了在測試中使用。它有 近期遭到系統移除 目前全面將其移除 基礎架構

  • Capability Requested:這項事件是導入為暫時解決方案, 提供 fuchsia.logger/LogSink 連線的元件屬性。開始時間 那麼,這項功能也會用來 fuchsia.debugdata/Publisher 個連線。這不該是非常長的 及長期解決方案因為事件系統僅適用於具有特殊權限的元件 使用「元件事件」建構這項功能是低承諾的。 我們瞭解,如果使用案例增加,那就開始構思出 更標準化的解決方案目前的計畫將設法移除 活動,但先將該活動列入特定客戶許可清單: Archivist、偵錯資料和測試管理員 (用於偵錯資料)。

  • Directory Ready:這個事件是為了提供 由元件公開給 Archivist 的 out/diagnostics 目錄 接著檢查資料匯總作業診斷團隊已規劃為 VMO 設計提供支援 。鑑於記錄在元件啟動前需要取得記錄檔 服務目錄時,這個方法就已過時。新的 提供檢查及記錄 VMO 給 Archivist 的解決方案 確保記錄檔會在元件發生前 就會啟動非同步迴圈現階段,提案是將這項活動加入許可清單 並設法完全移除它。

轉送 CML 語法

使用
{
    use: [
        {
            event_stream: [
                "running",
                "started",
                "stopped",
            ],
            from: "parent",
            mode: "async",
            path: "/my_stream"
        },
    ]
}

使用宣告內容包含:

  • event_stream:單一事件名稱或事件名稱清單。
  • from:能力的來源。允許的值:父項或子項 參照。不得使用架構或本身事件。
  • path:放送事件串流的路徑。。時間 因此,該元件的傳入命名空間會包含服務檔案,其中包含 元件管理員的 fuchsia.component.EventStream 指定名稱 放送 (請參閱使用)。如未提供,元件可以使用 EventSource 可開始從特定時間點取用事件。
  • scope:使用父項事件時,可以使用 scope 來參照 縮小事件範圍至特定子項範圍,否則該事件就會 來自父項的範圍
  • mode:預設為 async。如前所述, 同為非同步因此,只有許可清單中的測試才能使用模式 「同步」直到完全消除模式為止這個欄位最後會將 。
  • filter:目前僅適用於 DiagnosticsReadyCapabilityRequested。如前所述,這些事件即將遭到移除 完全不會提供篩選器詳情,因為篩選器不相關 給非診斷開發人員

此外,也可使用來自不同來源的事件。在 舉例來說,元件會取得單一事件串流,其中包含 startedstopped 事件的範圍取決於父項提供,以及 started 子項 #child 啟動時。

use: [
  {
    event_stream: [
      {
        name: [ "started", "stopped ],
        from: "parent",
      },
      {
        name: "started",
        from: "framework",
        scope: "#child",
      }
    ]
  }
]
優惠
{
    offer: [
        {
            event_stream: "started",
            from: [ "#child_a", "parent", ],
            to: "#archivist",
            as: "started_foo"
        },
    ]
}

優惠聲明內容包含:

  • event_stream:單一事件名稱或事件名稱清單。
  • scope:透過架構提供事件時,範圍可讓一個範圍 定義事件關聯的子項 (或子項陣列)。如果 未指定範圍,範圍為「本身」,表示事件與 元件本身針對父項提供事件時,範圍允許 則可將事件縮小至子項範圍
  • from:能力的一或多個來源。如果有多個來源 因為串流視為合併允許的值:架構、 父項或子項參照不得提供自己的產品/服務。
  • to:提供能力的子項參照。
  • as:能力的目標名稱 (重新命名)。請注意, 已有指定單一事件串流名稱時觸發
公開
{
    expose: [
        {
            event_stream: "started",
            from: "framework",
            scope: [ "#child", "#other_child" ],
            as: "foo_started"
        },
    ]
}

公開宣告內容包含:

  • event_stream:單一事件名稱或事件名稱清單。
  • scope:從 framework 公開事件時,必須指定範圍, 可讓您定義事件的子項 (或子項陣列) 介紹生成式 AI 模型
  • from:一或多個能力來源。如果有多個來源 因為串流視為合併允許的值:父項或 子項參照不得公開事件。
  • as:能力的目標名稱 (重新命名)。請注意, 已有指定單一事件串流名稱時觸發

EventSource 通訊協定

EventSource 是一種通訊協定,可讓元件執行個體訂閱 事件串流。這是任何元件都能從 framework 使用的內建能力 使用明確轉送到這些 Pod 的事件。

靜態事件串流

靜態事件串流可讓您透過 傳入的 /events 目錄。與執行階段訂閱 EventSource.Subscribe,事件可以緩衝並觸發 元件抵達時啟動

元件會宣告將特定路徑和元件管理員中的事件串流use 就會依據特定路徑,在傳入的命名空間中建立一個項目 由元件管理員提供的 fuchsia.component.EventStream (請參閱 用途)。

事件會在內部進行緩衝,直到執行 GetNext 呼叫為止。 這個緩衝區將在實作期間決定 (可能是大型緩衝區或 下一個批次或其他項目的大小上限) 並清楚地呈現 刊載於 FIDL API 和事件說明文件中如果緩衝區數量 事件超過指定數量 (因消費者速度太慢) 元件 管理員會捨棄事件並關閉連線。接著,元件 會在準備好接收活動時重新連線。由於缺少 使用 Zircon 流量控制項我們希望避免無法如願以償 是否可以反轉向提供 EventStream 通訊協定 (即 而非元件管理員) 而且此外,我們也避免 例如元件管理工具的記憶體容量客戶行為良好,使用 如此一來,您就不必擔心遺失事件。客戶 太慢擷取事件時,便會收到捨棄事件的通知。這將 都是透過所用串流中的事件發生。一對情侶 執行此通知的替代方案可能是:

  • 相同類型的事件包含錯誤酬載,指出 都使用了原始類型
  • fuchsia.component.EventErrorPayload 下的特殊欄位:dropped。這個 欄位會包含 EventType,以及表示 列出已捨棄的事件
  • 通訊協定中的 FIDL 事件,事件發生時,用戶端會收到 包括捨棄的網站數量和類型這個替代方法 則可導入另一個 DoS 向量 事件。

FIDL API

在撰寫本文件時,使用事件的通訊協定為 定義於 fuchsia.sys2/events.fidl。本提案包含幾項異動 目標是將通訊協定和結構升級為 fuchsia.component 並在 SDK 中提供:

元件管理員將提供 EventStream,而非元件

這意味著將 EventSource#Subscribe 變更為接受要求:

[Discoverable]
protocol EventSource {
    Subscribe(vector<EventSubscription> events, request<EventStream> stream)
        -> () error fuchsia.component.Error;
};

EventStream.GetNext 會提供批次事件

因為元件管理員現在如上所述,提供通訊協定和批次事件 新的串流通訊協定會在上個章節中傳回一批事件 GetNext,而非單一事件。

protocol EventStream {
    GetNext() -> vec<Event>;
};

已捨棄「TakeStaticEventStream

移除 EventSource.TakeStaticEventStream 方法,以便將 如上所述,將事件串流直接傳入傳入的命名空間 專區。

嚴格:EventEventResult

在撰寫本文件時,這幾類資料都是資料表。不過 相關定義明確,我們不應該加入更多資料。目的地: 我們可以消除處理選填欄位的方式提升人體工學 struct 和非彈性聯集:

struct Event {
    EventHeader header;
    EventResult event_result;
};


union EventResult {
    1: EventPayload payload;
    2: EventError error;
};

實作

此設計大多已實作完畢。還有一些需要 ,再於 SDK 中公開這個 API。請特別注意以下幾點:

  • 將活動加入許可清單:directory readyrunningcapability requested
  • 將靜態事件串流放入傳入的命名空間,並移除 EventStream.TakeStaticEventStream 方法。
  • 自今天我們規劃了 events,希望將 event streams 可合併於轉送中的請求
  • 提供「高於根層級」整個拓撲的事件到根目錄,然後 在事件轉送宣告中導入 scope 關鍵字, 含有來自拓撲內子樹狀結構的事件
  • 公開事件。在撰寫這份文件時,我們只支援 offeruse
  • 在來源事件中,事件現在只會參照單一元件,但 向根領域提供「高於根層級」的所有 Pod 資源轉送之後 因此可以參照多個元件

成效

事件系統以現有的內部掛鉤系統為基礎 因此,軟體管理元件會 無法將事件分派給對這些元件感興趣的其他元件。 事實上,當某個元件 目前只關注單一元件的事件,而非整個子樹狀結構 可以只為該元件分派事件 子樹狀結構,可減少參與的 syscall 數量。

人體工學

此 RFC 導入了事件人體工學的改進:

  • 如果元件對單一元件事件感興趣,現在您可以 ,不必編寫程式碼來篩選。
  • 所有元件現在均內建 EventSource 通訊協定 而且不需要明確轉送
  • 某項能力會轉送 event stream,而不是轉送 events 且使用 event streams
  • 可以在轉送過程中合併 Event streams,減少轉送量 開發人員必須編寫 CML 格式的陳述式

回溯相容性

這項變更並不會破壞相容性。將採用內層結構 在元件管理員層級 (以及根、核心、啟動領域) 重構 但無法在用戶端元件中此外,也會在測試中重構 使用事件 (所有樹狀結構內),因為事件將與單一元件有關 您的兒時朋友不久後就會遭到解僱 並要求您暫時保密

安全性和隱私權注意事項

本提案維護安全性與隱私權討論的安全性屬性 審查結果。先前 EventSource 通訊協定已明確轉送 因為事件有關整個子樹狀結構這個通訊協定已內建 和事件是關於特定元件整體事件 子樹狀結構已明確轉送,且可對 確保非特殊權限的元件不會收到這類事件。

測試

所有事件功能和語意都必須在元件中完成整合測試 聯絡。

說明文件

如需更新說明文件,請前往事件功能 和「元件資訊清單」頁面。

缺點、替代方案和未知

提供從元件到架構的 EventSink 能力

在此概念下,元件會將通訊協定 RealmEventSink 公開給 這個架構的重點在於架構接著會開啟這項能力,並將事件推送至 即時更新。本提案並未明確界定 元件將取得事件,且沒有明確路徑可限制這類範圍 或是能靜態確認元件無法從 部分拓撲中不應有瀏覽權限目前價格底下 則是能以靜態方式呈現特定集合相關的事件 元件類別 (適用於一般用途) 或整體子樹狀結構 (如 來診斷實際工作環境和測試中的用途)。

公開和優惠轉送聲明的自我來源

selfexpose/offer活動留待日後設計作業的開放區域 元件可能公開及調度的自訂事件數。

既有藝術品和參考資料

如需事件目前狀態的說明文件,請前往 事件功能事件 FIDL 定義