在线协作编辑OT算法简介

一、背景

在线文档,简单的来说,这些产品的模式都是富文本编辑器+后台,富文本编辑器产生内容、展示内容,然后后台负责保存。

富文本编辑器的产品和技术已经非常成熟了,像codeMirror,当然本身实现也非常复杂,不是这里要讨论的,我们要讨论的问题是:在线文档编辑的时候产生冲突怎么办?

二、协同编辑冲突场景示例

举个很简单的例子,现在大家的文本都是‘aaab’A用户在第3个字符行后面插入了一个‘c’B用户在第3个字符行后面插入了一个‘d’,这个时候A这边看到的是‘aaacb’,B这边看到的是‘aaadb’,我们假设A用户先提交了数据,那其实最后预期的数据其实应该是‘aaacdb’,这样就最大的保存了每个人的输入。

那我们现在来看看正常情况下这里会发生什么:

  • A用户:A本地已经是‘aaacb’了,过一会儿,后台告诉它B也编辑了,编辑的行为就是第3个字符行后面插入了一个‘d’,那A这边执行了这个行为,最终变成了‘aaadcb’
  • B用户:B本地已经是‘aaadb’了,过一会儿,后台告诉它A也编辑了,编辑的行为就是第3个字符行后面插入了一个‘c’,那B这边执行了这个行为,最终变成了‘aaacdb’

从上面的模拟过程可以看到,A用户最后的结果其实是不正确的,但是B是正确的

这里先解释一下大家可能会疑惑的地方:为什么B是过一会儿后台告诉它A编辑了,不是说A先提交了数据吗?
其实这里针对的是冲突场景,这里如果B在提交之前,已经收到后台告诉它A编辑了,那其实就是顺序编辑了,也就不是冲突了。所以这里假设的场景指的是A、B几乎同时提交,但是A到达后台还是快一点的,也就是A、B在编辑的时候是不知道彼此的存在的

真实的冲突场景其实不是这种简单的时序问题,这里我后面再介绍。

三、尝试解决协同编辑冲突

解决方案一:丢弃

这可能是最简单粗暴的方法了,发现有冲突后不处理,直接丢弃,这明显不是让用户无法接受。

解决方案二:锁

上面出现问题是因为大家编辑了都立即应用了,我们编辑后不立即应用不就好了,而且历史告诉我们,有冲突加锁应该可以解决。那假如不立即应用,有没有什么处理办法:

  • A用户:A本地已经是‘aaab’了,A编辑了,但是不应用,先发后台
  • B用户:B本地已经是‘aaab’了,B编辑了,但是不应用,先发后台
  • 后台:后台先收到A请求,然后加了一个锁,然后收到了B请求,这时侯应该是加锁的状态,所以接受了A,拒绝了B
  • A用户:A用户收到了后台的回复,告诉它你的提交我接收了
  • B用户:B用户收到了后台的回复,告诉它你的提交被我拒绝了,因为冲突了

这样虽然能继续下去,但是好像还是不太行,B的提交还是丢了,所以好像和第一种简单粗暴的方法没啥区别。

解决方案三:OT算法

好了,不绕弯子,OT算法才是重点。回到上面的例子,本质问题还是因为后台通知大家的B的编辑行为看起来不太对。

现在后台通知大家的是:B的编辑的行为就是3个字符行后面插入了一个‘d’,但是在A已经接受的情况下,正确的通知应该是:B的编辑的行为就是4个字符行后面插入了一个‘d’。

假如我们把A提交的行为叫做A,B提交的行为叫做B,现在后台就是一个简单的转发功能,告诉A的是B,告诉B的是A,然后就出现问题了。所以后台应该更聪明一点,它应该学会一个招术,那就是把每个人提交的行为转变一下再告诉别人,其实这个技术就是OT算法。

OT算法全名叫Operation Transformation,你看从名字就对应了上面我说的转变算法。

假设我们的OT算法的转换功能叫transform,那transform(A,B)= A',B'。

也就是说你输入两个先后执行的行为,它会告诉你两个转换过后的行为,然后把A'行为告诉B,把B'行为告诉A,这样大家再应用就相安无事了。

preview

上面的图是OT的经典菱形图,也就是说A会变成A'在B这边执行,B会变成B'在A这边执行。
这里实际抽象一下,用户永远就只有两个人,一个是自己,一个是服务端,只是服务端的操作可能来自很多人,如果不这样抽象,那一个个进行冲突处理可能会让你觉得无法理解。
那我们现在再来看看后台有了OT这个能力之后会发生什么:

A用户:A本地已经是‘aaacb’了,过一会儿,后台告诉它B也编辑了,编辑的行为就是4个字符行后面插入了一个‘d’,那A这边执行了这个行为,最终变成了‘aaacdb’。

B用户:B本地已经是‘aaadb’了,过一会儿,后台告诉它A也编辑了,编辑的行为就是3个字符行后面插入了一个‘c’,那B这边执行了这个行为,最终变成了‘aaacdb’。

现在A、B就一致了!

四、小结

其实OT对应的只是一种思想,具体怎么实现是根据具体情况来区分的,比如我们现在讨论的就是文本的OT,那有可能图的OT、表格的OT又是其他的实现。OT的核心就是transform,而transform的核心就在于你怎么找到这样的原子操作了,然后原子操作的复杂度决定了transform实现的复杂度。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rs勿忘初心

您的鼓励将是我的最大创动原动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值