Skip to content

Commit e3d59e7

Browse files
Fix document duplication with out-of-band changes (#535)
* Fix document duplication with out-of-band changes * Fix types * Review
1 parent 1952a51 commit e3d59e7

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

plugins/yjs/fps_yjs/routes.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,13 @@ async def serve(self, websocket: YWebsocket, permissions) -> None:
256256
file_type,
257257
file_format,
258258
document,
259+
room,
259260
)
260261
)
261262
# update the document when file changes
262263
if file_id not in self.watchers:
263264
self.watchers[file_id] = create_task(
264-
self.watch_file(file_format, file_id, document),
265+
self.watch_file(file_format, file_id, document, room),
265266
self.task_group,
266267
)
267268

@@ -317,7 +318,13 @@ async def get_file_path(self, file_id: str, document) -> str | None:
317318
document.path = file_path
318319
return file_path
319320

320-
async def watch_file(self, file_format: str, file_id: str, document: YBaseDoc) -> None:
321+
async def watch_file(
322+
self,
323+
file_format: str,
324+
file_id: str,
325+
document: YBaseDoc,
326+
room: YRoom,
327+
) -> None:
321328
file_path = await self.get_file_path(file_id, document)
322329
assert file_path is not None
323330
logger.info("Watching file", path=file_path)
@@ -332,11 +339,17 @@ async def watch_file(self, file_format: str, file_id: str, document: YBaseDoc) -
332339
self.file_id.unwatch(file_path, watcher)
333340
file_path = new_file_path
334341
# break
335-
await self.maybe_load_file(file_format, file_path, file_id)
342+
await self.maybe_load_file(file_format, file_path, file_id, room)
336343
if file_id in self.watchers:
337344
del self.watchers[file_id]
338345

339-
async def maybe_load_file(self, file_format: str, file_path: str, file_id: str) -> None:
346+
async def maybe_load_file(
347+
self,
348+
file_format: str,
349+
file_path: str,
350+
file_id: str,
351+
room: YRoom,
352+
) -> None:
340353
model = await self.contents.read_content(file_path, False)
341354
# do nothing if the file was saved by us
342355
assert model.last_modified is not None
@@ -347,10 +360,19 @@ async def maybe_load_file(self, file_format: str, file_path: str, file_id: str)
347360
documents = [v for k, v in self.documents.items() if k.split(":", 2)[2] == file_id]
348361
for document in documents:
349362
document.source = model.content
363+
assert room.ystore is not None
364+
await room.ystore.encode_state_as_update(room.ydoc)
350365
self.last_modified[file_id] = to_datetime(model.last_modified)
351366

352367
def on_document_change(
353-
self, file_id: str, file_type: str, file_format: str, document: YBaseDoc, target, event
368+
self,
369+
file_id: str,
370+
file_type: str,
371+
file_format: str,
372+
document: YBaseDoc,
373+
room: YRoom,
374+
target,
375+
event,
354376
) -> None:
355377
if target == "state" and "dirty" in event.keys:
356378
dirty = event.keys["dirty"]["newValue"]
@@ -361,17 +383,22 @@ def on_document_change(
361383
# e.g. a new cell added to a notebook
362384
document.unobserve()
363385
document.observe(
364-
partial(self.on_document_change, file_id, file_type, file_format, document)
386+
partial(self.on_document_change, file_id, file_type, file_format, document, room)
365387
)
366388
if file_id in self.savers:
367389
self.savers[file_id].cancel(raise_exception=False)
368390
self.savers[file_id] = create_task(
369-
self.maybe_save_document(file_id, file_type, file_format, document),
391+
self.maybe_save_document(file_id, file_type, file_format, document, room),
370392
self.task_group,
371393
)
372394

373395
async def maybe_save_document(
374-
self, file_id: str, file_type: str, file_format: str, document: YBaseDoc
396+
self,
397+
file_id: str,
398+
file_type: str,
399+
file_format: str,
400+
document: YBaseDoc,
401+
room: YRoom,
375402
) -> None:
376403
# save after configured delay to prevent too frequent saving
377404
await sleep(self.config.document_save_delay)
@@ -386,6 +413,8 @@ async def maybe_save_document(
386413
if self.last_modified[file_id] < to_datetime(model.last_modified):
387414
# file changed on disk, let's revert
388415
document.source = model.content
416+
assert room.ystore is not None
417+
await room.ystore.encode_state_as_update(room.ydoc)
389418
self.last_modified[file_id] = to_datetime(model.last_modified)
390419
return
391420
if model.content != document.source:

0 commit comments

Comments
 (0)