aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/roster.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-12 00:17:32 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-12 00:17:32 +0200
commit14911aae21ec4975f7a805b91e3c4867cb41974b (patch)
tree8c00230a88053905fd77938f3a9539efeb4c3094 /packages/meshbay-node/src/meshbay_node/roster.py
parentf6f107e02c7a4aa7326c9a82310a239327d81ed6 (diff)
downloadmeshbay-14911aae21ec4975f7a805b91e3c4867cb41974b.tar.gz
feat: let the operator pause and resume a root's indexing (MNP 6.2)
A whole-root walk now checks its root before every file: removed or ejected, it stops instead of reading the drive to the end; paused, it finishes from the hash cache alone. A paused root is not watched, not swept by reconcile and survives a restart (roster), its indexed files stay served. Resume runs the reconcile sweep over the root, so entries and their enrichment are kept. Signed root_pause / root_resume over MNP, loopback routes, CLI `root pause|resume`, a pause button on the indexing dock and pause/resume in the roots table of Group settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/roster.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/roster.py25
1 files changed, 25 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/roster.py b/packages/meshbay-node/src/meshbay_node/roster.py
index a5d1967..9336e38 100644
--- a/packages/meshbay-node/src/meshbay_node/roster.py
+++ b/packages/meshbay-node/src/meshbay_node/roster.py
@@ -737,6 +737,31 @@ class Roster:
return {r["key"][len(prefix):] for r in rows
if r["key"].startswith(prefix) and r["value"] == "auto"}
+ # Whether the operator paused a root's indexing. Kept here beside
+ # `root_ejected:` for the same reasons: runtime state rather than
+ # configuration, and a pause that a restart undid would start the very scan
+ # the operator stopped.
+ SETTING_ROOT_PAUSED_PREFIX = "root_paused:"
+
+ @classmethod
+ def root_paused_key(cls, root_name: str) -> str:
+ return cls.SETTING_ROOT_PAUSED_PREFIX + fold(root_name)
+
+ async def set_root_paused(self, group_id: str, root_name: str,
+ paused: bool, set_by: str = "") -> None:
+ await self.set_setting(group_id, self.root_paused_key(root_name),
+ "1" if paused else "0", set_by)
+
+ async def paused_roots(self, group_id: str) -> set[str]:
+ """The folded names of this group's paused roots — matched like `ejected_roots`."""
+ prefix = self.SETTING_ROOT_PAUSED_PREFIX
+ async with self._db.execute(
+ "SELECT key, value FROM group_settings WHERE group_id = ?",
+ (group_id,)) as cur:
+ rows = await cur.fetchall()
+ return {r["key"][len(prefix):] for r in rows
+ if r["key"].startswith(prefix) and r["value"] == "1"}
+
async def get_setting(self, group_id: str, key: str,
default: str | None = None) -> str | None:
async with self._db.execute(