RFC-0168:通过 InspectSink 公开检查

RFC-0168:通过 InspectSink 公开 Inspect
状态已接受
领域
  • 诊断
  • 组件框架
说明

定义组件公开 Inspect 的机制。

问题
  • 100583
  • 93344
Gerrit 更改
  • 680702
作者
审核人
提交日期(年-月-日)2022-05-17
审核日期(年-月-日)2022-06-15

总结

此 RFC 引入了 fuchsia.diagnostics.InspectSink 协议,该协议可让组件公开 Inspect 数据。因此,现在可以移除当前机制(DirectoryReady 事件)。

设计初衷

目前的检查通过一种与常规组件框架功能路由不一致的机制公开。如今,组件向其传出命名空间中的 diagnostics 目录向框架公开。

为了在 SDK 中发布事件功能,DirectoryReady 事件在 RFC-121 中已标记为“已弃用”。不过,对于在此目录不存在的情况下组件如何公开 Inspect 数据,我们尚未提供有效的解决方案。此外,Fuchsia 上的 Flutter 希望摆脱我们对文件系统抽象的依赖,并简化其实现。重新考虑组件公开 Inspect 的方式将有助于消除运行时的大幅复杂性,并为开发者的工效学设计带来优势。

利益相关方

教员:leannogasawara@google.com

审核者

  • crjohns@google.com
  • geb@google.com
  • shayba@google.com

咨询人员

  • dworsham@google.com
  • surajmalhotra@google.com
  • zarvox@google.com

社交:此 RFC 以前以 Google 文档文档的形式在诊断、组件框架、Flutter 和其他应用中进行了社交。

设计

背景

以前,Archivist 曾通过 /hub 提取 Inspect 数据。其代码库的结构设计为 hub 上的目录观察器,会在出现 out/diagnostics 目录时开始跟踪组件的检查数据(当时的名称不同)。最终,此过程最终通过事件(在 appmgr 和组件管理器中)移除和完成。在那时,读取 Inspect 数据的测试是直接从 /hub 读取的。

Archivist 目前依赖 DirectoryReady 事件来做两件事:

  • 从组件(组件 expose /diagnostics to framework)中提取检查数据。
  • 将检查数据归因于源组件。

DirectoryReady 事件可以处理这两个点。不过,我们已经为 (2) 使用了 CapabilityRequested,作者认为我们可以使用常规协议(类似于 fuchsia.logger.LogSink)来处理 (1),从而带来其他优势。

解决归因不是此 RFC 的目标。这将留作日后移除 CapabilityRequested 事件(目前用于 LogSinkDebugData)的工作。

检查接收器

此 RFC 引入了 InspectSink 协议,该协议允许 Archivist 从组件中提取检查数据。此协议的定义如下:

library fuchsia.diagnostics;

using zx;

@discoverable
protocol InspectSink {
    /// Publishes a handle to the `fuchsia.inspect.Tree` protocol that the server can use to read
    /// Inspect data, including lazy nodes.
    Publish(struct {
        tree fuchsia.inspect.Tree;
        root zx.handle:<VMO, zx.rights.BASIC | zx.rights.READ | zx.rights.MAP, optional>;
    });

    /// Publishes a read handle to the inspect VMO  that the component asynchronously updates.
    /// The server can read Inspect using the Inspect reader algorithm [1]. A component using this
    /// method to publish Inspect won't be able to expose lazy nodes.
    ///
    /// [1]: /docs/reference/platform-spec/diagnostics/inspect-vmo-format.md#reader_algorithm
    PublishVmo(struct {
        name string;
        root zx.handle:<VMO, zx.rights.BASIC | zx.rights.READ | zx.rights.MAP>;
    });
}

主要方法是 Publish,大多数组件都将使用它,因为 fuchsia.inspect.Tree 是公开 Inspect 的标准方式。不过,我们提供了一种机制,仅允许组件发布检查 VMO。您需要这样做是出于以下几个原因:

  • 如果某个组件不需要是服务器,就不必是服务器(没有理由运行异步循环,只使用功能,不提供任何内容),但应该仍然能够公开 Inspect。
  • 在驱动程序迁移到使用 fuchsia.inspect.Tree问题)之前,它们将继续公开 VMO。
  • 在 Inspect Dart 库支持 fuchsia.inspect.Tree 之前,需要继续公开 VMO。

fuchsia.logger.LogSink 一样,此协议将由 Archivist 提供并路由到组件。

与提供 out/diagnostics 目录相比,此协议具有多项优势:

  1. 与标准组件协议路由保持一致:

    • 组件仅使用 fuchsia.inspect.InspectSink 协议,而非执行 expose /diagnostics to framework,这与组件目前导出日志和跟踪记录的方式类似。
    • 归档人员可以通过 CapabilityRequested 接收与其的连接,从而保持归因。
  2. 在启动组件异步循环之前,检查数据是否可用。

    • 目录由 fuchsia.io.Directory 提供支持,大多数组件在启动异步循环之前不会提供其 out 目录。通过使用此协议,快照可以包含尚未启动其异步循环但已写入 Inspect 数据的组件的 Inspect 数据。

    • 这同样适用于 fuchsia.inspect.Tree 协议。在组件开始提供此协议之前,该组件的检查数据在快照中不可用,但在大多数情况下,这种情况在组件开始其异步循环之前不会发生。通过使用上面建议的协议,我们可以立即为 Archivist 提供根 VMO(这样至少包含此 VMO)以及 fuchsia.inspect.Tree 的句柄,以供将来的请求使用。

  3. 运行程序和文件系统实现不会再出现问题。

    • 目前,appmgr 和组件管理器中的代码可以用于特殊情况,即组件未按时提供 out/diagnostics 的情况,Flutter 运行程序就是这种情况。该运行程序会先传送 out/ 目录,然后再进行填充。理想情况下,我们仅使用目录监视器,但并非所有 VFS 实现都已实现监视器(特别是 Flutter 使用的 C++ SDK 中的 VFS 实现),并且我们无法依赖于使用完整 fuchsia.io.Directory 实现的未来运行程序。

这项变更可以在后台完成,具体方法是将 inspect/client.shard.cml 更改为使用新协议,而不是向框架公开诊断目录。文件 inspect/client.shard.cml 通过 SDK 提供,可供在任何位置公开 Inspect 的所有组件使用。

此方案适用于 v2 组件。为了确保兼容性,我们仍会处理 v1 组件的 out/diagnostics。随着向 v2 的不断迁移,作者认为花时间改变 v1 的工作方式不值得。目标是在后台进行此项更改,因此迁移到 v2 的组件不需要更改有关其公开检查方式的代码更改。

实现

之后,我们会遵循标准的 LSC 流程。

具体步骤如下:

  1. 在 Archivist 中实现新协议 InspectSink
  2. 使用 inspect/client.shard.cml 识别组件,并将 fuchsia.inspect.InspectSink 从 Archivist 路由到这些组件。今天,这引入了必须在 CML 定义中完整枚举所有此类组件的问题,不过,我们有一个已实现社交的解决方案,后续的 RFC 中也会对此进行介绍。
  3. 更改 inspect/client.shard.cml 以使用此协议,同时向框架公开 /diagnostics 目录,从而允许软转换。
  4. 支持连接到 InspectSink,而不是在检查库中提供 diagnostics 目录。
  5. 从组件管理器中移除 DirectoryReady 的实现,并在所有组件转换完毕并且刷新所有预构建文件后,将其从 fuchsia.sys2.Event 定义中移除。我们将依赖 CTF 测试,以及我们必须知道何时可以完成的支持期限。

性能

性能应该会有积极的提升,因为我们无需再遍历目录或创建 DirectoryReady 事件,只需依靠单个协议即可。

安全注意事项

此更改与组件框架安全属性保持一致,特别是最小权限原则和分层隔离原则。

隐私注意事项

隐私权方面没有变化。检查数据继续流经常规隐私流水线。

测试

将通过以下方式测试此 RFC 的实现:

  • 在连接到 InspectSink 的库中进行了单元测试。
  • 在 Archivist(提供 InspectSink 服务)中进行了单元测试和集成测试。
  • 用于检测兼容性更改的 CTF 测试

文档

检查发现和托管将会更新。

目标是在后台进行此变更,在编写检查的库中。但是,如果我们最终在组件迁移到 v2 时需要更改代码,我们会将这些更改反映在迁移指南的诊断部分中。

缺点、替代方案和未知情况

一个同时适用于日志和 Inspect 的协议

我们可以创建一个 DiagnosticsSink,它允许组件在一个位置连接 Inspect 和日志。

  • 优点:使用一个协议(而不是 2 个)。
  • 缺点:如果由于某种原因,我们日后需要以不同方式处理日志或检查,那么通过为二者维护单独的协议可能会更容易。

我们认为,这种替代方案的缺点没有吸引力,因为日志和 Inspect 是不同的,因此分别对它们进行路由是合理的。

早期技术和参考资料

不适用