situ2001 / opensumi-core

🚀 A framework helps you quickly build Cloud or Desktop IDE products.
https://opensumi.com/zh
MIT License
0 stars 0 forks source link

[Stage1] Basic functions of collaboration #1

Closed situ2001 closed 2 years ago

situ2001 commented 2 years ago

Will be merged to: https://github.com/opensumi/core/pull/1274

Featrures

situ2001 commented 2 years ago

当前方案不够好,原因如下

  1. binding没有考虑到每一个uri对应的Resource拥有且只有一个TextModel,如果为每一个Group里的Tab都上一个Binding,在同一个resource被多个Group打开后,多个binding将会被创建出,此时,会出现同一个TextModel对应多个binding的情况。
  2. 对于1中出现的情况,当前的方案(编辑器不focus或者resource不为group的current的时候,选择性地关闭掉对应binding中部分事件监听)管理起来容易混乱——如果管理不当,将会出现注册了多次(n次)ytext和textmodel的事件监听的情况(比如,输入v却出现了n个v)。
  3. 还会出现多个同一个TextModel却有着不一样的UndoManager的情况,造成撤消重做的混乱——同一个Resource的不同tab的UndoManger是不一样的,当前的Editor不能撤消重做掉其他Editor对该TextModel的修改(同一个TextModel有着多个Binding对象的话,对应地就会有着多个不同的undomanger)

这几天重做掉它

situ2001 commented 2 years ago

目前采用TextModel与YText一对一的Binding,可以支持多个编辑器的选区和光标同步,编辑器通过对应的方法添加进去,并处理好了编辑器的事件监听函数的注册与销毁。

Todo

situ2001 commented 2 years ago

由于yjs的CRDT保证了一致性,强制保存文件到本地即可

Bug

目前仍存在的问题:如果在没有连接到ws server,那么在本地打开一个文件,将会检查空(同步前为空)的yMap,创建出一个新的yText对象(对方同理)后马上创建binding。在连接上ws server后,将会同步状态,此时,本机与对方对同一个Uri的Resource的TextModel的binding,绑定的将不会是同一个yText,因而两方的改动都不会被相互感知到。

目前的一个想法是:监听yMap的变化(增删改),然后更新对应的uri的binding 不,这样会导致修改被覆盖的情况出现——比如所有人都在ws连接成功前创建打开同一个Resource(有时间先后顺序),在ws成功连接后,只有最晚在YMap同一个key中创建的YText的那方的修改被保留,其他client的修改全部被覆盖。

situ2001 commented 2 years ago

A better solution

经过大致分析,出现这个问题的原因应该是:不确定是哪个用户进行yText的初始化,用户之间的并发访问yMap也比较难handle(个人认为可以在服务端放个mutex,所有用户来acquire这个锁)。

目前通信使用的是websocket,下午看了看y-websocket服务端的源码,发现服务端为每一个room都存了一份yDoc,因此可以考虑在打开文件时,在服务端操作这份yDoc,进行yText的初始化。客户端只需要监听yMap即可(也可以试着使用top-level yText)

准备尝试——node侧负责yMap的增删改操作,browser侧只负责yMap.has以及监听并响应yMap的add与delete操作

Todo

situ2001 commented 2 years ago

进度:初始化好Node侧服务,准备书写yText初始化逻辑。目前是打算把前端获得的TextModel的text string给传到后端(当检查yMap后发现没有对应uri的yText)

situ2001 commented 2 years ago

进度:已完善Browser端的基本测试

situ2001 commented 2 years ago

进度:已完善Node端的基本测试