From 92e6b9823119b5461efc304a81e79e186a928e6d Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Wed, 7 Oct 2026 21:31:10 +0200 Subject: perf(node): list a group's directories off the event loop Every full index walked all roots on the loop, and a node with several large roots stopped answering for seconds. Walk directories only, on the roots' disk thread; index_sync is spawned and still answers on failure. Co-Authored-By: Claude Opus 5.5 --- .../src/meshbay_node/transport/webrtc/files.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc/files.py') diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/files.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/files.py index f629563..0434554 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/files.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/files.py @@ -19,7 +19,7 @@ from meshbay_node.transport.webrtc.disk import ( _rmdir_if_empty, ) from meshbay_node.transport.webrtc.limits import CHUNK_SIZE, LEASE_GRANTED, LEASE_QUEUED -from meshbay_node.transport.wire import index_sync_message +from meshbay_node.transport.wire import index_sync_message, list_dirs_off_loop log = logging.getLogger("meshbay_node.transport.webrtc_server") @@ -177,9 +177,21 @@ class FilesMixin: self._audit("dir_delete", rel) self._send({"type": MNP.DIR_DELETE_ACK, "v": MNP_VERSION, "dir": rel}) - def _do_index_sync(self) -> None: - ctx = self._group_ctx() - self._send(index_sync_message(ctx["index"], ctx.get("roots"), self._hidden_ids())) + async def _do_index_sync(self) -> None: + try: + dirs = await list_dirs_off_loop(self._group_ctx().get("roots")) + # Read again after the walk: the entries go out as they are when the + # reply is sent, so no delta pushed meanwhile is older than it. + ctx = self._group_ctx() + msg = index_sync_message(ctx["index"], ctx.get("roots"), self._hidden_ids(), + dirs) + except Exception as e: + # What the dispatcher answered when this ran inline. A spawned task + # that fails only logs, and the client would wait out its timeout. + log.error("Error building index_sync: %s", e, exc_info=True) + self._send({"type": "error", "detail": "Request failed"}) + return + self._send(msg) async def _try_serve_thumbnail( self, thumb_hash: str, chunk_index: int, gek: bytes | None, -- cgit v1.2.3