@@ -29,7 +29,7 @@ class YRoom:
2929 room_id := "{file_type}:{file_format}:{file_id}"
3030 """
3131
32- _jupyter_ydoc : YBaseDoc
32+ _jupyter_ydoc : YBaseDoc | None
3333 """JupyterYDoc"""
3434 _ydoc : pycrdt .Doc
3535 """Ydoc"""
@@ -65,23 +65,34 @@ def __init__(
6565 self ._client_group = YjsClientGroup (room_id = room_id , log = self .log , loop = self ._loop )
6666 self ._ydoc = pycrdt .Doc ()
6767 self ._awareness = pycrdt .Awareness (ydoc = self ._ydoc )
68- _ , file_type , _ = self .room_id .split (":" )
69- JupyterYDocClass = cast (
70- type [YBaseDoc ],
71- jupyter_ydoc_classes .get (file_type , jupyter_ydoc_classes ["file" ])
72- )
73- self ._jupyter_ydoc = JupyterYDocClass (ydoc = self ._ydoc , awareness = self ._awareness )
74-
75- # Initialize YRoomFileAPI and begin loading content
76- self .file_api = YRoomFileAPI (
77- room_id = self .room_id ,
78- jupyter_ydoc = self ._jupyter_ydoc ,
79- log = self .log ,
80- loop = self ._loop ,
81- fileid_manager = fileid_manager ,
82- contents_manager = contents_manager
83- )
84- self .file_api .load_ydoc_content ()
68+
69+ # If this room is providing global awareness, set
70+ # `file_api` and `jupyter_ydoc` to `None` as this room
71+ # will never read/write via the `ContentsManager`.
72+ if self .room_id == "JupyterLab:globalAwareness" :
73+ self .file_api = None
74+ self ._jupyter_ydoc = None
75+ else :
76+ # Otherwise, initialize `jupyter_ydoc` and `file_api`
77+ _ , file_type , _ = self .room_id .split (":" )
78+ JupyterYDocClass = cast (
79+ type [YBaseDoc ],
80+ jupyter_ydoc_classes .get (file_type , jupyter_ydoc_classes ["file" ])
81+ )
82+ self ._jupyter_ydoc = JupyterYDocClass (ydoc = self ._ydoc , awareness = self ._awareness )
83+
84+ # Initialize YRoomFileAPI and begin loading content
85+ self .file_api = YRoomFileAPI (
86+ room_id = self .room_id ,
87+ jupyter_ydoc = self ._jupyter_ydoc ,
88+ log = self .log ,
89+ loop = self ._loop ,
90+ fileid_manager = fileid_manager ,
91+ contents_manager = contents_manager
92+ )
93+ self .file_api .load_ydoc_content ()
94+ self ._jupyter_ydoc .observe (self ._on_jupyter_ydoc_update )
95+
8596
8697 # Start observers on `self.ydoc` and `self.awareness` to ensure new
8798 # updates are broadcast to all clients and saved to disk.
@@ -91,7 +102,6 @@ def __init__(
91102 self ._ydoc_subscription = self ._ydoc .observe (
92103 self ._on_ydoc_update
93104 )
94- self ._jupyter_ydoc .observe (self ._on_jupyter_ydoc_update )
95105
96106 # Initialize message queue and start background task that routes new
97107 # messages in the message queue to the appropriate handler method.
@@ -118,7 +128,12 @@ async def get_jupyter_ydoc(self):
118128 (`jupyter_ydoc.ybasedoc.YBaseDoc`) after waiting for its content to be
119129 loaded from the ContentsManager.
120130 """
121- await self .file_api .ydoc_content_loaded
131+ if self .file_api :
132+ await self .file_api .ydoc_content_loaded
133+ if self .room_id == "JupyterLab:globalAwareness" :
134+ message = "There is no Jupyter ydoc for global awareness scenario"
135+ self .log .error (message )
136+ raise Exception (message )
122137 return self ._jupyter_ydoc
123138
124139
@@ -127,7 +142,8 @@ async def get_ydoc(self):
127142 Returns a reference to the room's YDoc (`pycrdt.Doc`) after
128143 waiting for its content to be loaded from the ContentsManager.
129144 """
130- await self .file_api .ydoc_content_loaded
145+ if self .file_api :
146+ await self .file_api .ydoc_content_loaded
131147 return self ._ydoc
132148
133149
@@ -155,7 +171,8 @@ async def _process_message_queue(self) -> None:
155171 """
156172 # Wait for content to be loaded before processing any messages in the
157173 # message queue
158- await self .file_api .ydoc_content_loaded
174+ if self .file_api :
175+ await self .file_api .ydoc_content_loaded
159176
160177 # Begin processing messages from the message queue
161178 while True :
@@ -448,7 +465,8 @@ async def stop(self) -> None:
448465 # Remove all observers, as updates no longer need to be broadcast
449466 self ._ydoc .unobserve (self ._ydoc_subscription )
450467 self ._awareness .unobserve (self ._awareness_subscription )
451- self ._jupyter_ydoc .unobserve ()
468+ if self ._jupyter_ydoc :
469+ self ._jupyter_ydoc .unobserve ()
452470
453471 # Finish processing all messages, then stop the queue to end the
454472 # `_process_message_queue()` background task.
@@ -457,4 +475,5 @@ async def stop(self) -> None:
457475
458476 # Finally, stop FileAPI and return. This saves the final content of the
459477 # JupyterYDoc in the process.
460- await self .file_api .stop ()
478+ if self .file_api :
479+ await self .file_api .stop ()
0 commit comments