RFC-0168:通过 InspectSink 公开 Inspect | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 定义组件公开 Inspect 的机制。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 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
事件(目前用于 LogSink
和 DebugData
)的工作。
检查接收器
此 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
目录相比,此协议具有多项优势:
与标准组件协议路由保持一致:
- 组件仅使用
fuchsia.inspect.InspectSink
协议,而非执行expose /diagnostics to framework
,这与组件目前导出日志和跟踪记录的方式类似。 - 归档人员可以通过
CapabilityRequested
接收与其的连接,从而保持归因。
- 组件仅使用
在启动组件异步循环之前,检查数据是否可用。
目录由
fuchsia.io.Directory
提供支持,大多数组件在启动异步循环之前不会提供其out
目录。通过使用此协议,快照可以包含尚未启动其异步循环但已写入 Inspect 数据的组件的 Inspect 数据。这同样适用于
fuchsia.inspect.Tree
协议。在组件开始提供此协议之前,该组件的检查数据在快照中不可用,但在大多数情况下,这种情况在组件开始其异步循环之前不会发生。通过使用上面建议的协议,我们可以立即为 Archivist 提供根 VMO(这样至少包含此 VMO)以及fuchsia.inspect.Tree
的句柄,以供将来的请求使用。
运行程序和文件系统实现不会再出现问题。
- 目前,appmgr 和组件管理器中的代码可以用于特殊情况,即组件未按时提供
out/diagnostics
的情况,Flutter 运行程序就是这种情况。该运行程序会先传送out/
目录,然后再进行填充。理想情况下,我们仅使用目录监视器,但并非所有 VFS 实现都已实现监视器(特别是 Flutter 使用的 C++ SDK 中的 VFS 实现),并且我们无法依赖于使用完整fuchsia.io.Directory
实现的未来运行程序。
- 目前,appmgr 和组件管理器中的代码可以用于特殊情况,即组件未按时提供
这项变更可以在后台完成,具体方法是将 inspect/client.shard.cml
更改为使用新协议,而不是向框架公开诊断目录。文件 inspect/client.shard.cml
通过 SDK 提供,可供在任何位置公开 Inspect 的所有组件使用。
此方案适用于 v2 组件。为了确保兼容性,我们仍会处理 v1 组件的 out/diagnostics
。随着向 v2 的不断迁移,作者认为花时间改变 v1 的工作方式不值得。目标是在后台进行此项更改,因此迁移到 v2 的组件不需要更改有关其公开检查方式的代码更改。
实现
之后,我们会遵循标准的 LSC 流程。
具体步骤如下:
- 在 Archivist 中实现新协议
InspectSink
。 - 使用
inspect/client.shard.cml
识别组件,并将fuchsia.inspect.InspectSink
从 Archivist 路由到这些组件。今天,这引入了必须在 CML 定义中完整枚举所有此类组件的问题,不过,我们有一个已实现社交的解决方案,后续的 RFC 中也会对此进行介绍。 - 更改
inspect/client.shard.cml
以使用此协议,同时向框架公开/diagnostics
目录,从而允许软转换。 - 支持连接到
InspectSink
,而不是在检查库中提供diagnostics
目录。 - 从组件管理器中移除
DirectoryReady
的实现,并在所有组件转换完毕并且刷新所有预构建文件后,将其从fuchsia.sys2.Event
定义中移除。我们将依赖 CTF 测试,以及我们必须知道何时可以完成的支持期限。
性能
性能应该会有积极的提升,因为我们无需再遍历目录或创建 DirectoryReady
事件,只需依靠单个协议即可。
安全注意事项
此更改与组件框架安全属性保持一致,特别是最小权限原则和分层隔离原则。
隐私注意事项
隐私权方面没有变化。检查数据继续流经常规隐私流水线。
测试
将通过以下方式测试此 RFC 的实现:
- 在连接到 InspectSink 的库中进行了单元测试。
- 在 Archivist(提供 InspectSink 服务)中进行了单元测试和集成测试。
- 用于检测兼容性更改的 CTF 测试。
文档
检查发现和托管将会更新。
目标是在后台进行此变更,在编写检查的库中。但是,如果我们最终在组件迁移到 v2 时需要更改代码,我们会将这些更改反映在迁移指南的诊断部分中。
缺点、替代方案和未知情况
一个同时适用于日志和 Inspect 的协议
我们可以创建一个 DiagnosticsSink,它允许组件在一个位置连接 Inspect 和日志。
- 优点:使用一个协议(而不是 2 个)。
- 缺点:如果由于某种原因,我们日后需要以不同方式处理日志或检查,那么通过为二者维护单独的协议可能会更容易。
我们认为,这种替代方案的缺点没有吸引力,因为日志和 Inspect 是不同的,因此分别对它们进行路由是合理的。
早期技术和参考资料
不适用