树中的同步引擎

除非另有说明,否则可以在 此处找到引擎实现

请阅读 同步简介

客户端

clients 引擎是一个特殊的引擎,因为它对用户是不可见的,并且不能被禁用 - 可以将其视为“元”引擎。因此,它实际上没有 storetracker 的合理概念。

该引擎主要负责在其自己的记录中保持 clients 集合的最新状态。同步的某些部分使用此集合来了解存在哪些其他客户端以及它们上次同步的时间(尽管其中很多正在转向使用 Firefox 账户设备)。

客户端还可以处理 commands - 简而言之,其他一些客户端可以写入此客户端的 commands,当此客户端注意到时,它将执行该命令。命令不是任意的,因此命令必须为双方理解才能工作。有一些命令可以“清除”集合等。在实践中,这仅在设备还原书签时由 bookmarks 使用 - 在这种情况下,还原设备将向所有其他客户端发送 wipe 命令,以便它们采用新的书签而不是合并它们。

如果不是因为这种有点有限的 commands 功能,该引擎可以被认为已弃用并由 FxA 设备取代 - 但是因为我们不能仅仅删除对命令的支持,并且也没有计划替换它们,所以客户端引擎仍然很重要。

书签

bookmarks 引擎已更改,使其与 places 数据库紧密集成。它没有外部 tracker,跟踪已集成到 Places 中。每个书签都有一个 syncStatus 和一个 syncChangeCounter,这些由 places 在内部管理。然后,同步只需通过查找这些字段来查询已更改的书签。

书签有点独特,因为它需要维护树结构,这使得合并成为一项挑战。 dogear 组件(用 Rust 编写,也由 应用程序服务书签组件 使用)执行此合并。

书签还率先提出了“镜像”的概念 - 这是一个数据库表,它精确地跟踪服务器上的内容。因为每次同步只从服务器获取自上次同步以来的更改,所以每次同步都不会提供服务器上的每个记录。但是,合并代码确实需要知道服务器上的内容 - 因此镜像跟踪此内容。

历史记录

历史记录类似于上面描述的书签 - 它与 places 密切集成 - 但由于不涉及树结构,因此不太复杂。

历史记录的一个独特特征是,该引擎采取措施来 *不* 上传所有内容 - 旧的配置文件往往拥有过多的历史记录,无法合理地存储和上传,因此上传通常限制在最近的 5000 次访问。

登录信息

登录信息也已升级为与 Services.logins 密切集成 - 登录信息组件本身管理元数据。

标签页

标签页是一个特殊的引擎,因为它根本没有底层存储 - 它既保存了此设备当前打开的标签页(每次更新时都会枚举),也让 Firefox 的其他部分知道其他设备上打开了哪些标签页。没有数据库 - 如果我们尚未同步,我们不知道其他哪些标签页已打开,当我们知道时,该列表仅存储在内存中。

SyncedTabs 模块 是浏览器用来从其他设备获取标签页列表的主要接口。

附加组件

附加组件仍然是一个“老式”引擎,它有一个跟踪器和存储,它们没有与附加组件管理器紧密集成。因此,它相当复杂且容易出错 - 例如,它保留“最后已知”状态以便它知道要同步什么,而更好的模型是让附加组件管理器代表同步跟踪更改。

它还尝试同步主题等。鉴于它在移动平台上不起作用,因此该引擎的未来尚不清楚。

地址/信用卡

地址和信用卡的同步功能与存储紧密绑定。与上面其他引擎不同,此引擎一直与之紧密绑定,因为我们在意识到这种紧密绑定是一个特性而不是一个错误之后才编写它。

从技术上讲,这是 2 个单独的引擎和集合。但是,由于底层存储使用共享实现,因此同步也使用共享实现 - 即,对两者都使用相同的逻辑 - 因此在实践中我们倾向于将它们视为一个引擎。

因此,services/sync/modules/engines/ 目录中只有一个 shim,而实际逻辑位于 存储实现旁边

此引擎对上面描述的“镜像”概念有独特的处理方式 - 每当对字段进行更改时,该字段的原始值都会直接存储在存储中。这意味着在下一次同步时,可以推断出服务器上记录的值,这意味着可以执行“三方”合并,因此它可以更好地区分本地专用、远程专用或冲突的更改。

WebExt-Storage

webext-storage 是用 Rust 实现的,位于 应用程序服务 中,并被引入到 附加组件代码 中 - 请注意,这包括存储 *和* 同步代码。同步引擎本身是同步目录中的一个 shim。

有关如何集成 Rust 引擎的更多信息,请参阅 Rust 引擎的实现方式 文档。