RFC-0165:SDK 类别

RFC-0165:SDK 类别
状态已接受
区域
  • 开发者
说明

SDK Atom 具有用于描述其成熟度和目标受众群体的类别。

Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-05-13
审核日期(年-月-日)2022-05-31

摘要

每个 SDK Atom 都有一个类别,用于定义哪些类型的 SDK 使用方可以看到该 Atom。随着 SDK Atom 的成熟,我们可以提高其曝光度,这意味着提高其稳定性保证。

设计初衷

Fuchsia 的构建方式是将许多不同的组件组合在一起,这些组件使用 FIDL 中定义的架构与协议进行交互。Fuchsia 项目中的组件使用与第三方编写的组件与 Fuchsia 平台交互的相同机制相互交互。因此,我们可以使用一种统一的机制来开发 Fuchsia 和针对 Fuchsia 进行开发,这对我们来说很有帮助。

最简单的方法是将所有 FIDL 定义放入 Fuchsia SDK,然后让所有开发者在开发其组件时使用这些相同的 FIDL 定义。不过,这种方法会失效,因为设计 API 时会出现一个常见的矛盾:API 设计者需要能够迭代其设计,而 API 使用方需要稳定性,以便在 API 之上构建应用。

本文档介绍了 SDK 类别,这是一种平衡这些问题的现有机制。SDK 类别早于 RFC 流程。本文档仅记录现有机制。

SDK 类别并不是 Fuchsia 用来解决此问题的唯一机制。例如,Fuchsia 还通过 capability 路由限制了组件可以依赖的 FIDL 协议。这些机制是互补的,因为如果没有 capability 路由,组件作者可能会倾向于创建内部 FIDL 定义的本地副本,而不是等待将其添加到 SDK 中。同样,如果没有 SDK 类别,组件作者可以开始依赖内部 FIDL 协议在自己的组件之间进行通信。

利益相关方

哪些人对此 RFC 的接受与否有利益相关?(此部分为可选部分,但建议填写。)

教员

  • neelsa@google.com

Reviewers:

  • dschuyler@google.com
  • jamesr@google.com
  • jeremymanson@google.com
  • neelsa@google.com
  • sebmarchand@google.com
  • sethladd@google.com

社交

此 RFC 跳过了社会化阶段,因为该机制已完全实现。

定义

SDK Atom 是指可包含在 SDK 中的文件集合。Fuchsia 使用 GN 中的 sdk_atom 模板表示 SDK Atom。

SDK 目标是用于创建 SDK 的构建目标。例如,//sdk:core 是用于创建 Core SDK 的 build 目标的 GN 标签。将这些目标称为 IDK 目标可能更准确,因为它们会为 IDK 创建 JSON 元数据。SDK 生产流水线的后续阶段会使用此 JSON 元数据生成完全集成的 Fuchsia SDK(例如,使用 Bazel 等构建系统)。

设计

FIDL 库是 SDK Atom 的一个示例,但还有其他类型的 SDK Atom,包括 C++ 客户端库、文档和工具。SDK 类别适用于每种类型的 SDK Atom,但本文档使用 FIDL 库作为运行示例。

SDK 类别通过认识到不同的 API 使用方具有不同的稳定性需求,从而平衡 API 的迭代和稳定性需求。与 API 设计师“更近”的 API 使用方通常对稳定性的需求较低,并且通常是第一个向 API 设计师提供实现反馈的客户。

每个 SDK Atom 都带有 SDK 类别注解,该注解定义了哪些 SDK 使用方可以依赖于该 SDK Atom。例如,如果 fuchsia.foo FIDL 库的 SDK 类别为 internal,则表示只有 Fuchsia 项目中的 SDK 使用方可以依赖于 fuchsia.foo。如果有人想要更改 fuchsia.foo,则可能会破坏 Fuchsia 项目中的使用方,但不会破坏其他项目中的使用方。

再举一个例子,假设有一个 SDK 类别为 partnerfuchsia.bar FIDL 库,这意味着 fuchsia.bar 既可以在 Fuchsia 项目中使用,也可以由与 Fuchsia 项目建立合作伙伴关系的 SDK 使用1。当有人更改 fuchsia.bar 时,他们更有可能破坏使用方,因为他们可能会破坏依赖于 fuchsia.bar 的合作伙伴。

最后,假设有一个 SDK 类别为 publicfuchsia.qux FIDL 库,这意味着 fuchsia.qux 可供公众使用。更改 fuchsia.qux 非常危险,因为由普通大众开发的一组软件可能无限且不可知。

除了定义一系列逐渐增加的 API 使用方集之外,SDK 类别还定义了逐渐增加的稳定性时间范围。例如,fuchsia.foo 在一天之内可能会发生巨大变化,因为 internal 类别会限制对 Fuchsia 项目本身的曝光度。更改 fuchsia.foo 的用户可以同时更改所有客户端和服务器,这意味着 API 所需的稳定性时间窗口非常小或为零。

相比之下,Fuchsia 与合作伙伴项目签订的协议中包含了对兼容性时间范围的预期。例如,我们目前与合作伙伴达成了协议,将兼容性期限设为 6 周,但这个期限可能会在即将发布的 RFC 中发生变化。这项协定意味着 fuchsia.bar 一天内不能发生大幅变化。相反,我们需要以保持兼容性窗口的方式逐步更改 fuchsia.bar

目前,Fuchsia 没有任何 SDK 类别为 public 的 SDK Atom,这意味着 Fuchsia 尚未承诺支持使用其 API 的一般公众。不过,Fuchsia 项目将在某个时间点开始支持公众使用其 API。届时,Fuchsia 项目需要为这些 API 定义兼容性期限,该期限可能会比 partner API 的兼容性期限更长。

典型的 SDK Atom 会在 internal SDK 类别中开始其生命周期。在某个时候,API 委员会可能会将 SDK Atom 升级为 partner SDK 类别,通常是在合作伙伴需要访问 Atom 中包含的 API 时。未来某个时候,当 Fuchsia 有一个不为空的 public SDK 类别时,SDK Atom 也将能够从 partner 类别升级到 public 类别。某些 SDK Atom 可能会永久保留在 internal SDK 类别中。其他设备可能会升级到 partner,但永远不会升级到 public

此生命周期目前尚未完成,因为该生命周期不涵盖 SDK Atom 的废弃和移除。例如,我们可能需要为目前无用但仍具有历史价值的 SDK Atom 添加 historical 类别。对现有模型的此类扩展超出了本 RFC 的范围。

请注意,此机制与用于平台版本控制的 @available 机制相辅相成。@available 机制会记录 FIDL API 何时以及如何更改。SDK 类别机制决定了 API 设计师可以多快进行更改的政策

实现

用于构建 SDK 的 GN 规则中已实现 SDK 类别。每个 SDK Atom 都有一个 category 参数,该参数的值为以下值之一:

  • excluded:SDK 中可能不包含 Atom;
  • experimental:(此 SDK 类别没有多大意义);
  • internal:支持在 Fuchsia 平台源代码树中使用;
  • cts:支持在 Fuchsia 兼容性测试中使用;
  • partner:部分合作伙伴支持使用;
  • public:可供公众使用。

这些类别构成一个有序列表,受众群体呈单调递增趋势。例如,public 类别中的 SDK Atom 必须可供部分合作伙伴使用,因为 public 在此列表中位于 partner 之后。

experimental 类别没有多大意义,因为我们有更好的机制(例如GN visibility)来控制 Fuchsia 平台源代码树中的代码使用。此类别可能很快就会被移除。

每个 SDK 目标还具有 category 参数,用于定义该 SDK 的目标使用方集。构建系统会强制要求 SDK 目标中包含的所有内容都具有适合该受众群体的 SDK 类别。例如,partner 的 SDK 可以包含已获授权用于 public 的 SDK Atom(因为 public 在此列表中位于 partner 之后),但不能包含仅获授权用于 internal 的 SDK Atom(因为 internal 在此列表中位于 partner 之前)。

excluded SDK 类别用于进行二次检查,以防止某些目标永远不会包含在 SDK 中。实际上,excluded 是关于该 intent 的文档,也是供代码审核人员仔细考虑对该值所做的更改的钩子。

向后兼容性

通常,SDK 类别的变化是通过向越来越多的受众群体公开 SDK Atom 来实现的。缩减 SDK Atom 的使用方集会从其视图中有效删除这些 API,如果未正确协调,可能会破坏这些使用方。

安全注意事项

SDK 类别不是安全机制。恶意攻击者可以读取 Fuchsia 开源项目中的所有 FIDL 定义,并以攻击者能想象到的任何恶意方式使用这些定义。此机制仅限于让工程师流程更顺畅地运行。

隐私注意事项

与 SDK 类别及其适用的 SDK Atom 相关的所有信息都是公开的。

测试

SDK 类别是在构建时通过构建配置强制执行的。不过,我们对此机制的测试并不多。更改与 SDK 相关的 GN 模板可能会破坏该机制,从而允许 SDK Atom 包含在不适当的 SDK 目标中。我们有几个冗余机制(包括 SDK 清单)来捕获错误配置,但我们依赖于代码审核员发现 SDK 清单和 SDK 类别之间的不一致,以便在 SDK 类别机制中发现回归问题。

文档

编写此 RFC 的目的是记录 SDK 类别的当前状态。还有其他面向开发者的文档,介绍了 Fuchsia 对其发布的各种 SDK 做出的稳定性承诺。

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

这种方法的主要缺点是 SDK 类别的应用粒度较粗。例如,您可以想象另一种方法,即为各个 FIDL 协议元素分配 SDK 类别,类似于为各个协议元素分配 @available 属性的方式。

现有 SDK 类别机制的优势在于,它适用于所有类型的 SDK Atom。不过,对于某些类型的 SDK Atom(例如FIDL 协议)的变化。

在先技术和参考文档

大多数平台都有类似的机制,可随着 API 变得更加稳定而逐步扩大 API 的受众群体。例如,Apple 在为 macOS 和 iOS 开发 API 时使用了类似的机制。在这些操作系统的开发过程中,每个框架都有三组 API:框架本身提供的内部 API、可供操作系统 build 中的其他框架使用的私有 API,以及可供操作系统的一般公开 build 应用使用的公共 API。

某些其他平台的 SDK 发布流程中会包含“标头剥离”步骤,该步骤会在向更广泛的受众群体发布 SDK 之前从标头中移除文本。使用“未剥离”标头的使用方可以依赖于一组更大的 API,而使用剥离标头的使用方则可以依赖于一组更小的 API。此机制与 SDK 类别类似,但精细程度更高,并且通常具有更少的受众群体划分级别。


  1. 目前,这组合作伙伴尚未对外公开。随着项目的扩大,我们可能需要重新考虑合作伙伴关系的做法。