feat: live mesh peer gossip
When a peer's hello is verified, send a gossip burst of currently connected peers so the new peer can discover and connect to nodes it hasn't met yet — without relying on the anchor for a full peer-join notification for each one. - mesh: add PendingConnect chan for gossip-discovered peer IDs - peer: send gossip burst after hello; push unknown peers from incoming gossip onto PendingConnect (skip self + already-connected) - anchor: drain PendingConnect per runOnce, initiate startOffer for unknown peers using the same lexicographic tiebreak as anchor join; drain goroutine is scoped to the runOnce lifetime to avoid using stale sessions after a reconnect Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -100,6 +100,46 @@ func runOnce(ctx context.Context, anchorURL, netHash string, id *crypto.Identity
|
||||
|
||||
s := &sender{id: id, sendCh: sendCh}
|
||||
|
||||
// Drain gossip-discovered peers and initiate offers. Stopped when runOnce
|
||||
// returns (via drainDone) so stale sessions from a dead connection are never reused.
|
||||
drainDone := make(chan struct{})
|
||||
defer close(drainDone)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case pid, ok := <-m.PendingConnect:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
mu.RLock()
|
||||
_, already := sessions[pid]
|
||||
mu.RUnlock()
|
||||
if already {
|
||||
continue
|
||||
}
|
||||
// Use the same lexicographic tiebreak as anchor join to avoid
|
||||
// both sides trying to offer simultaneously.
|
||||
if strings.Compare(string(id.PeerID()), string(pid)) <= 0 {
|
||||
continue
|
||||
}
|
||||
go func(pid proto.PeerID) {
|
||||
sess, err := startOffer(ctx, pid, id, m, s)
|
||||
if err != nil {
|
||||
log.Printf("anchor: gossip offer to %s: %v", pid.Short(), err)
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
sessions[pid] = sess
|
||||
mu.Unlock()
|
||||
}(pid)
|
||||
case <-drainDone:
|
||||
return
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
var msg proto.AnchorMessage
|
||||
if err := wsjson.Read(ctx, conn, &msg); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user