RFC-0168:通过 InspectSink 公开 Inspect | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 定义组件公开 Inspect 的机制。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2022-05-17 |
审核日期(年-月-日) | 2022-06-15 |
摘要
此 RFC 介绍了 fuchsia.diagnostics.InspectSink
协议,该协议允许组件公开 Inspect 数据。因此,现在可以移除当前机制(DirectoryReady
事件)了。
设计初衷
目前,Inspect 是通过与常规组件框架功能路由不一致的机制公开的。目前,组件会将其传出命名空间中的 diagnostics
目录公开给框架。
为了在 SDK 中发布事件功能,DirectoryReady
事件已在 RFC-121 中被标记为已废弃。不过,我们尚未找到一个理想的解决方案,来解决如果此目录不存在,组件如何公开 Inspect 数据的问题。此外,Flutter on Fuchsia 还希望消除对这些文件系统抽象的依赖,并简化其实现。重新思考组件如何公开 Inspect 将有助于它们消除大量运行时复杂性,并为开发者的人体工学带来优势。
利益相关方
教练:leannogasawara@google.com
Reviewers:
- crjohns@google.com
- geb@google.com
- shayba@google.com
咨询了:
- dworsham@google.com
- surajmalhotra@google.com
- zarvox@google.com
共享:此 RFC 之前以 Google 文档的形式在诊断、组件框架、Flutter 等团队之间共享。
设计
背景
以前,归档程序通过 /hub
提取 Inspect 数据。其代码库的结构为中心上的目录监视器,这些监视器会在 out/diagnostics
目录出现(当时的名称有所不同)时开始跟踪组件的 Inspect 数据。此方法最终被移除,改为通过事件(在 appmgr 和组件管理器中)进行。此外,当时读取 Inspect 数据的测试是通过直接从 /hub
读取来实现的。
归档程序目前依赖于 DirectoryReady
事件来执行以下两项操作:
- 从组件(组件
expose /diagnostics to framework
)提取 Inspect 数据。 - 将检查数据归因于源组件。
DirectoryReady
事件可解决这两点。不过,我们已经有了 CapabilityRequested
来处理 (2),并且作者认为我们可以使用常规协议(类似于 fuchsia.logger.LogSink
)来处理 (1),从而获得额外优势。
解决归因问题并非本 RFC 的目标。我们将在日后移除目前用于 LogSink
和 DebugData
的 CapabilityRequested
事件。
InspectSink
此 RFC 介绍了 InspectSink
协议,该协议允许归档程序从组件提取 Inspect 数据。此协议定义如下:
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 的标准方式。不过,我们提供了一种机制,允许组件仅发布 Inspect VMO。我们之所以需要这样做,原因有以下几点:
- 如果组件不需要成为服务器,则无需成为服务器(没有理由运行异步循环,只使用功能,不提供任何内容),但仍应能够公开 Inspect。
- 在驱动程序迁移为使用
fuchsia.inspect.Tree
之前(问题),它们将继续公开 VMO。 - 在 Inspect Dart 库支持
fuchsia.inspect.Tree
之前,它需要继续公开 VMO。
与 fuchsia.logger.LogSink
一样,此协议将由归档程序提供并路由到组件。
与提供 out/diagnostics
目录相比,此协议具有以下几点优势:
与标准组件协议路由保持一致:
- 组件只需使用协议
fuchsia.inspect.InspectSink
,而无需执行expose /diagnostics to framework
,这与组件当前导出日志和轨迹的方式类似。 - 归档管理员可以通过
CapabilityRequested
接收与其相关联的连接,从而保持归因。
- 组件只需使用协议
您可以在启动组件异步循环之前提供检查数据。
目录由
fuchsia.io.Directory
支持,大多数组件在启动异步循环之前不会提供其out
目录。通过使用此协议,快照可以包含尚未启动异步循环但已写入 Inspect 数据的组件的 Inspect 数据。fuchsia.inspect.Tree
协议也是如此。只有在组件开始处理此协议后,快照中才会显示组件的 Inspect 数据。在大多数情况下,除非组件开始其异步循环,否则不会发生这种情况。通过使用上述协议,我们可以立即向归档程序提供根 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 提供,所有公开“随时随地检查”功能的组件都会使用该文件。
此提案适用于 v2 组件。出于兼容性考虑,我们仍会处理 v1 组件的 out/diagnostics
。由于我们正在逐步迁移到 v2,作者认为不值得花时间更改 v1 的运作方式。目标是在后台进行此更改,以便迁移到 v2 的组件无需更改其公开 inspect 的方式的代码。
实现
我们将遵循标准的 LSC 流程。
具体步骤如下:
- 在归档程序中实现新协议
InspectSink
。 - 使用
inspect/client.shard.cml
识别组件,并将fuchsia.inspect.InspectSink
从归档程序路由到这些组件。目前,这会导致必须在 cml 定义中完全枚举所有此类组件的问题,但我们已经提出了解决方案,并将在后续的 RFC 中进行介绍。 - 更改
inspect/client.shard.cml
以使用此协议,并将/diagnostics
目录公开给框架,从而实现平滑过渡。 - 支持连接到
InspectSink
,而不是在 Inspect 库中公开diagnostics
目录。 - 移除组件管理器中的
DirectoryReady
实现,并在所有组件都完成转换且所有预构建内容都已刷新后,从fuchsia.sys2.Event
定义中移除DirectoryReady
。我们将根据 CTF 测试和支持期限来确定何时可以完成此操作。
性能
由于我们不再需要遍历目录或创建 DirectoryReady
事件,只需依赖单个协议,因此性能应该会有所提升。
安全注意事项
此更改符合组件框架安全属性,尤其是最小权限原则和分层隔离原则。
隐私注意事项
隐私权方面没有任何变化。被检查的数据会继续通过常规隐私保护流水线。
测试
此 RFC 的实现将通过以下方式进行测试:
- 连接到 InspectSink 的库中的单元测试。
- 在 Archivist(用于 InspectSink)中进行了单元测试和集成测试。
- CTF 测试,用于检测兼容性变更。
文档
检查发现和托管将会更新。
目标是在后台的写入检查库中进行此更改。不过,如果我们最终要求在组件迁移到 v2 时进行代码更改,我们会在迁移指南的“诊断”部分反映这些更改。
缺点、替代方案和未知情况
一个适用于日志和检查的协议
我们可以使用 DiagnosticsSink,让组件能够在一个位置连接 Inspect 和日志。
- 优点:只需路由单个协议,而不是 2 个协议。
- 缺点:如果日后出于某种原因,我们需要对日志或“检查”进行不同的处理,那么如果我们为这两者维护不同的协议,可能比为这两者使用相同的协议更容易实现。
我们认为,由于日志和“检查”是不同的东西,因此这种替代方案的缺点使其非常不受欢迎,因此最好将它们单独路由。
在先技术和参考文档
不适用