Skip to content

Commit f8e8154

Browse files
committed
Support document fork
1 parent 179a146 commit f8e8154

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

pycrdt_websocket/yroom.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232

3333

3434
class YRoom:
35-
clients: list
35+
clients: set[Websocket]
36+
fork_ydocs: set[Doc]
3637
ydoc: Doc
3738
ystore: BaseYStore | None
3839
ready_event: Event
@@ -51,6 +52,7 @@ def __init__(
5152
ystore: BaseYStore | None = None,
5253
exception_handler: Callable[[Exception, Logger], bool] | None = None,
5354
log: Logger | None = None,
55+
ydoc: Doc | None = None,
5456
):
5557
"""Initialize the object.
5658
@@ -74,13 +76,14 @@ def __init__(
7476
returns True if the exception was handled.
7577
log: An optional logger.
7678
"""
77-
self.ydoc = Doc()
79+
self.ydoc = Doc() if ydoc is None else ydoc
7880
self.awareness = Awareness(self.ydoc)
7981
self.ready_event = Event()
8082
self.ready = ready
8183
self.ystore = ystore
8284
self.log = log or getLogger(__name__)
83-
self.clients = []
85+
self.clients = set()
86+
self.fork_ydocs = set()
8487
self._on_message = None
8588
self.exception_handler = exception_handler
8689
self._stopped = Event()
@@ -147,13 +150,19 @@ async def _broadcast_updates(self):
147150
return
148151
# broadcast internal ydoc's update to all clients, that includes changes from the
149152
# clients and changes from the backend (out-of-band changes)
150-
for client in self.clients:
151-
try:
152-
self.log.debug("Sending Y update to client with endpoint: %s", client.path)
153-
message = create_update_message(update)
154-
self._task_group.start_soon(client.send, message)
155-
except Exception as exception:
156-
self._handle_exception(exception)
153+
for ydoc in self.fork_ydocs:
154+
ydoc.apply_update(update)
155+
156+
if self.clients:
157+
message = create_update_message(update)
158+
for client in self.clients:
159+
try:
160+
self.log.debug(
161+
"Sending Y update to remote client with endpoint: %s", client.path
162+
)
163+
self._task_group.start_soon(client.send, message)
164+
except Exception as exception:
165+
self._handle_exception(exception)
157166
if self.ystore:
158167
try:
159168
self._task_group.start_soon(self.ystore.write, update)
@@ -245,7 +254,7 @@ async def serve(self, websocket: Websocket):
245254
"""
246255
try:
247256
async with create_task_group() as tg:
248-
self.clients.append(websocket)
257+
self.clients.add(websocket)
249258
sync_message = create_sync_message(self.ydoc)
250259
self.log.debug(
251260
"Sending %s message to endpoint: %s",
@@ -296,6 +305,6 @@ async def serve(self, websocket: Websocket):
296305
)
297306
tg.start_soon(client.send, message)
298307
# remove this client
299-
self.clients = [c for c in self.clients if c != websocket]
308+
self.clients.remove(websocket)
300309
except Exception as exception:
301310
self._handle_exception(exception)

0 commit comments

Comments
 (0)