feat: M4 gossip ops and UX
Refs #1 - /v1/diff endpoint returns each node's fingerprint set + tombstoned auto-thread status - knox gossip diff <peer-url>: shows peer-only/local-only fingerprints (pull/keep preview) and tombstone divergence (resolved-on-peer vs would-resurrect) - knox gossip sync: one-shot anti-entropy sweep + reconcile - gossip server starts before initial seed so peers can reach a booting node; KNOX_PEER_ADDR alone now serves without KNOX_PEERS - integration tests for diff + tombstone reporting - e2e verified: two live daemons, diff previewed 1655 peer-only fps, sync converged second node to 1655 observations
This commit is contained in:
+15
-14
@@ -50,6 +50,21 @@ func (w *Watcher) Start() error {
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
// Start the gossip server first so peers can reach us while the initial
|
||||
// seed is still ingesting. Vault/dirs are logged after the seed below.
|
||||
gossipAddr := ListenAddr()
|
||||
node := &Node{Kdb: w.knoxDB, Name: "knox", Addr: gossipAddr}
|
||||
srv := &http.Server{Addr: gossipAddr, Handler: node.Handler()}
|
||||
go func() {
|
||||
log.Printf("[knox] gossip listening on %s", gossipAddr)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("[knox] gossip server: %v", err)
|
||||
}
|
||||
}()
|
||||
if peers := PeerAddrs(); len(peers) > 0 {
|
||||
log.Printf("[knox] gossip peers: %v", peers)
|
||||
}
|
||||
|
||||
w.seed(watcher)
|
||||
log.Printf("[knox] watching %d directories", len(w.dirs))
|
||||
|
||||
@@ -57,20 +72,6 @@ func (w *Watcher) Start() error {
|
||||
log.Printf("[knox] obsidian vault: %s", w.vault)
|
||||
}
|
||||
|
||||
// Gossip: serve our observation log to peers and periodically converge.
|
||||
gossipAddr := ListenAddr()
|
||||
if peers := PeerAddrs(); len(peers) > 0 {
|
||||
node := &Node{Kdb: w.knoxDB, Name: "knox", Addr: gossipAddr}
|
||||
srv := &http.Server{Addr: gossipAddr, Handler: node.Handler()}
|
||||
go func() {
|
||||
log.Printf("[knox] gossip listening on %s", gossipAddr)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("[knox] gossip server: %v", err)
|
||||
}
|
||||
}()
|
||||
log.Printf("[knox] gossip peers: %v", peers)
|
||||
}
|
||||
|
||||
debounceMap := make(map[string]time.Time)
|
||||
browserTicker := time.NewTicker(browserInterval)
|
||||
giteaTicker := time.NewTicker(10 * time.Minute)
|
||||
|
||||
Reference in New Issue
Block a user