From 4b987791220dccc879f9813831e96c9aed28fcad Mon Sep 17 00:00:00 2001 From: lichenblankie Date: Fri, 5 Jun 2026 01:58:32 +0000 Subject: [PATCH] gossip sync: sync with random 20 peers per cycle instead of all peers --- README.md | 2 ++ tinyweb_forum/db.py | 7 ++++++- tinyweb_forum/sync.py | 8 +++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72d04e4..75a3493 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ All moderation is local — you control your view: - Forum instances auto-discover each other via RNS announces - Content is exchanged as JSON over RNS links every 5 minutes - Peer discovery propagates through gossip — each instance shares its known peers +- At scale (>20 peers), sync uses random gossip: each cycle picks 20 random peers instead of all peers +- This ensures content converges epidemically regardless of network size (content reaches all nodes within ~O(log N) cycles) - Block lists and retractions are gossiped alongside content - Only new/updated content is transferred (timestamp-based) - Auto-discovery can be disabled in the moderation page diff --git a/tinyweb_forum/db.py b/tinyweb_forum/db.py index 6ab12de..8a77715 100644 --- a/tinyweb_forum/db.py +++ b/tinyweb_forum/db.py @@ -54,9 +54,14 @@ class ForumDB: "CREATE TABLE IF NOT EXISTS synced_instances (" " instance_hash TEXT PRIMARY KEY," " name TEXT DEFAULT ''," - " last_sync TEXT DEFAULT ''" + " last_sync TEXT DEFAULT ''," + " status TEXT DEFAULT 'active'" ")" ) + try: + db.execute("ALTER TABLE synced_instances ADD COLUMN status TEXT DEFAULT 'active'") + except Exception: + pass db.execute( "CREATE TABLE IF NOT EXISTS settings (" " key TEXT PRIMARY KEY," diff --git a/tinyweb_forum/sync.py b/tinyweb_forum/sync.py index 440479d..ab4e7b3 100644 --- a/tinyweb_forum/sync.py +++ b/tinyweb_forum/sync.py @@ -1,4 +1,5 @@ import json +import random import threading import time import RNS @@ -6,6 +7,7 @@ import RNS FORUM_APP = "tinyweb-forum" SYNC_INTERVAL = 300 # 5 minutes REQUEST_TIMEOUT = 60 +GOSSIP_FANOUT = 20 # random peers to sync per cycle class _ForumAnnounceHandler: @@ -90,7 +92,11 @@ class ForumSync: while self._running: try: instances = self.fdb.get_synced_instances() - for inst in instances: + # Gossip: sync with random subset for scaling + # If <= GOSSIP_FANOUT peers, sync with all (current behavior) + # If more, sync with random FANOUT per cycle — content spreads epidemically + random.shuffle(instances) + for inst in instances[:GOSSIP_FANOUT]: if not self._running: break try: