Skip to content

Commit

Permalink
Update jupyter_ydoc and pycrdt_websocket dependencies (#367)
Browse files Browse the repository at this point in the history
* Update jupyter_ydoc and pycrdt_websocket dependencies (and indirectly pycrdt)

* linting

* Remove useless enumerate

* Update the connected users on global awareness changes

* Apply suggestions from code review

Co-authored-by: David Brochart <[email protected]>

* Test if the transcient room is the global awareness to observe it

* typing

---------

Co-authored-by: David Brochart <[email protected]>
  • Loading branch information
brichet and davidbrochart authored Oct 16, 2024
1 parent fea37f0 commit 2e3cf4a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 30 deletions.
58 changes: 31 additions & 27 deletions projects/jupyter-server-ydoc/jupyter_server_ydoc/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import time
import uuid
from logging import Logger
from typing import Any
from typing import Any, Literal
from uuid import uuid4

from jupyter_server.auth import authorized
from jupyter_server.base.handlers import APIHandler, JupyterHandler
from jupyter_server.utils import ensure_async
from jupyter_ydoc import ydocs as YDOCS
from pycrdt import Doc, UndoManager, YMessageType, write_var_uint
from pycrdt import Doc, UndoManager, write_var_uint
from pycrdt_websocket.websocket_server import YRoom
from pycrdt_websocket.ystore import BaseYStore
from tornado import web
Expand Down Expand Up @@ -137,6 +137,10 @@ def exception_logger(exception: Exception, log: Logger) -> bool:
exception_handler=exception_logger,
)

if self._room_id == "JupyterLab:globalAwareness":
# Listen for the changes in GlobalAwareness to update users
self.room.awareness.observe(self._on_global_awareness_event)

try:
await self._websocket_server.start_room(self.room)
except Exception as e:
Expand Down Expand Up @@ -286,31 +290,6 @@ async def on_message(self, message):
"""
message_type = message[0]

if message_type == YMessageType.AWARENESS:
# awareness
skip = False
changes = self.room.awareness.get_changes(message[1:])
added_users = changes["added"]
removed_users = changes["removed"]
for i, user in enumerate(added_users):
u = changes["states"][i]
if "user" in u:
name = u["user"]["name"]
self._websocket_server.connected_users[user] = name
self.log.debug("Y user joined: %s", name)
for user in removed_users:
if user in self._websocket_server.connected_users:
name = self._websocket_server.connected_users[user]
del self._websocket_server.connected_users[user]
self.log.debug("Y user left: %s", name)
# filter out message depending on changes
if skip:
self.log.debug(
"Filtered out Y message of type: %s",
YMessageType(message_type).name,
)
return skip

if message_type == MessageType.CHAT:
msg = message[2:].decode("utf-8")

Expand Down Expand Up @@ -405,6 +384,31 @@ async def _clean_room(self) -> None:
self._emit(LogLevel.INFO, "clean", "Loader deleted.")
del self._room_locks[self._room_id]

def _on_global_awareness_event(
self, topic: Literal["change", "update"], changes: tuple[dict[str, Any], Any]
) -> None:
"""
Update the users when the global awareness changes.
Parameters:
topic (str): `"update"` or `"change"` (`"change"` is triggered only if the states are modified).
changes (tuple[dict[str, Any], Any]): The changes and the origin of the changes.
"""
if topic != "change":
return
added_users = changes[0]["added"]
removed_users = changes[0]["removed"]
for user in added_users:
u = self.room.awareness.states[user]
if "user" in u:
name = u["user"]["name"]
self._websocket_server.connected_users[user] = name
self.log.debug("Y user joined: %s", name)
for user in removed_users:
if user in self._websocket_server.connected_users:
name = self._websocket_server.connected_users.pop(user)
self.log.debug("Y user left: %s", name)

def check_origin(self, origin):
"""
Check origin
Expand Down
2 changes: 1 addition & 1 deletion projects/jupyter-server-ydoc/jupyter_server_ydoc/rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(
self._file_format: str = file_format
self._file_type: str = file_type
self._file: FileLoader = file
self._document = YDOCS.get(self._file_type, YFILE)(self.ydoc)
self._document = YDOCS.get(self._file_type, YFILE)(self.ydoc, self.awareness)
self._document.path = self._file.path

self._logger = logger
Expand Down
4 changes: 2 additions & 2 deletions projects/jupyter-server-ydoc/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ authors = [
]
dependencies = [
"jupyter_server>=2.11.1,<3.0.0",
"jupyter_ydoc>=2.0.0,<4.0.0",
"jupyter_ydoc>=2.1.2,<4.0.0",
"pycrdt",
"pycrdt-websocket>=0.14.2,<0.15.0",
"pycrdt-websocket>=0.15.0,<0.16.0",
"jupyter_events>=0.10.0",
"jupyter_server_fileid>=0.7.0,<1",
"jsonschema>=4.18.0"
Expand Down

0 comments on commit 2e3cf4a

Please sign in to comment.