前端系统设计 - 设计即时共编文件系统 (Collaborative Editor)

2024年4月1日

💎 加入 E+ 成長計畫 與超過 350+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

本篇详细解说本收录在 E+ 的前端系统设计专题

前一篇 前端系统设计 - 设计聊天系统 (Chat System) 中,我们谈了聊天系统。在这一篇,我们将来讨论云端共编文件。

大家可以把即时共编文件理解成一个协作的编辑器 (collaborative editor),如果抽象化来思考,各类的云端共编文件,不论是常见的 Google Doc、Notion,或者是 VS Code 之前推出的共编 Live Share 功能,甚至是设计工具 Figma,其实概念都是一样,需要支援多人同时针对某个编辑器进行操作。

当然因为具体支援的功能很不同,在设计的细节上也会有所不同。举例来说,Notion 会需要支援各类的资料库,但是 Figma 则是需要支援各类的媒体类别。因此,最开始的问题厘清仍是最重要的。

这边列出推荐在最开始可以询问的厘清问题:

  • 这个系统的目标用户是谁? 上面提的 Google Doc、Notion、Figma 等,目标族群很不同,都是即时共编系统,但设计上会有差异
  • 最基本的功能涵盖什么? 除了文件编辑与阅览外,需要有历史记录、版本控制吗?
  • 文件是纯文字的吗? 还是要支援不同多媒体? 例如图片、语音、影片等
  • 有预期在多使用者同时编辑同一段落时,要如何处理冲突吗?
  • 要支援离线 (offline) 功能吗? 如果要的话,是阅读与编辑都支援吗?

除了上面这些,还有细部可以问的,包含:

  • 要有通知的功能吗?
  • 需要有评论或注解的功能吗?
  • 需要有文字的游标表示吗? 例如许多即时共编文件,会显示谁正在编辑哪一段落

即时共编文件的本质

即时共编文件,是当你打了某个新的内容时,在其他装置的使用者的文件中,也会出现该新增的内容。同样地,如果你做了修改或删除,其他装置的使用者文件中的该内容,也会被及时修改与删除。

从架构的角度来看

如前一段提到,从架构的角度来看,即时共编文件,与即时聊天的性质非常相似。具体来说,也会有个客户端的存储,以及客户端的控制器来处理同步的问题。客户端的 UI 会是以跟客户端存储同步为主,而由客户端控制器来处理客户端存储与伺服器端的同步。

以 Notion 来说,当今天输入内容到文件中,客户端会呼叫 /saveTransactions 的 API,但在 API 回传成功之前,Notion 就已经会把内容更新到画面上,达到低延迟感的使用体验。这时画面显示的资料,就会是跟客户端存储同步的。

这边的 /saveTransactions 中的 transaction 就是每一个在 Notion 文件的操作 (与对资料库操作的交易概念类似)。而如果今天输入内容到一半断线, /saveTransactions 传送失败,这时会需要有一个重新尝试 (retry) 的机制 ,以 Notion 为例,会是每隔几秒重新打 /saveTransactions API 来尝试。

与聊天系统相似的,是文件系统也会有短时间同时输入许多内容,因此需要有机制来确保不会每打一个字,就呼叫 API 来与后端同步。在这部分,可以用防抖 (debounce) 来实践即可。换句话说,当在连续输入时,不会马上呼叫 /saveTransactions API,而是当打字有停下时,才会触发 /saveTransactions

同样与聊天系统相似,即时共编文件系统也会透过一个伫列 (queue) 来做控管。Notion 的官方部落格是这样描述,当呼叫新增内容到文件后“这笔交易会被储存到 TransactionQueue 当中,TransactionQueue 负责将所有交易发送至 Notion 的伺服器,借此保存你的资料并与协作者分享。 the transaction is saved into TransactionQueue, the part of the client responsible for sending all transactions to Notion’s servers so your data is persisted and shared with collaborators. ”

本文为 E+ 成长计划的深度内容,截取前三分之一开放免费阅读。欢迎加入 E+ 成长计划阅读完整版本 (点此了解 E+ 的详细介绍)

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們