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 还通过功能路由限制了组件可以依赖的 FIDL 协议。这些机制是互补的,因为如果没有功能路由,组件作者可能会倾向于创建内部 FIDL 定义的本地副本,而不是等待它们添加到 SDK 中。同样,如果没有 SDK 类别,组件作者可能会开始依赖内部 FIDL 协议在其自己的组件之间进行通信。

利益相关方

哪些人会受到此 RFC 是否被接受的影响?(此部分为可选,但建议填写。)

辅导员

  • neelsa@google.com

审核者

  • 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 的 build 目标。例如,//sdk: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 项目中的使用方出现问题,但不会导致其他项目中的使用方出现问题。

再举一个例子,假设有一个 fuchsia.bar FIDL 库,其 SDK 类别为 partner,这意味着 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 Atom 的 SDK 类别为 public,这意味着 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 设计者可以多快进行更改的政策

实现

已在 GN 规则中实现 SDK 类别,用于构建 SDK。 每个 SDK Atom 都有一个 category 参数,其值如下所示:

  • excluded:Atom 可能未包含在 SDK 中;
  • 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 是关于该意图的文档,也是一个钩子,用于提醒代码审核者仔细考虑对该值的更改。

向后兼容性

通常,SDK 类别会通过向越来越大的受众群体公开 SDK Atom 来更改。缩小 SDK Atom 的使用方范围实际上会从这些使用方的视图中删除相应 API,如果未正确协调,可能会导致这些使用方出现问题。

安全注意事项

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

隐私注意事项

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

测试

SDK 类别在 build 时通过 build 配置强制执行。不过,我们对这种机制的测试不多。更改与 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,以及面向为操作系统构建应用的公众可用的公共 API。

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


  1. 目前,合作伙伴名单不公开。随着项目规模的扩大,我们可能需要重新审视合作伙伴关系的处理方式。