|
|
|
|
@ -55,10 +55,10 @@ type Spider struct {
@@ -55,10 +55,10 @@ type Spider struct {
|
|
|
|
|
mode string |
|
|
|
|
|
|
|
|
|
// Configuration
|
|
|
|
|
adminRelays []string |
|
|
|
|
followList [][]byte |
|
|
|
|
adminRelays []string |
|
|
|
|
followList [][]byte |
|
|
|
|
relayIdentityPubkey string // Our relay's identity pubkey (hex)
|
|
|
|
|
selfURLs map[string]bool // URLs discovered to be ourselves (for fast lookups)
|
|
|
|
|
selfURLs map[string]bool // URLs discovered to be ourselves (for fast lookups)
|
|
|
|
|
|
|
|
|
|
// State management
|
|
|
|
|
mu sync.RWMutex |
|
|
|
|
@ -235,6 +235,10 @@ func (s *Spider) mainLoop() {
@@ -235,6 +235,10 @@ func (s *Spider) mainLoop() {
|
|
|
|
|
|
|
|
|
|
log.I.F("spider: main loop started, checking every %v", MainLoopInterval) |
|
|
|
|
|
|
|
|
|
// Do an immediate check on startup
|
|
|
|
|
log.I.F("spider: performing initial connection check") |
|
|
|
|
s.updateConnections() |
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case <-s.ctx.Done(): |
|
|
|
|
@ -243,7 +247,7 @@ func (s *Spider) mainLoop() {
@@ -243,7 +247,7 @@ func (s *Spider) mainLoop() {
|
|
|
|
|
log.I.F("spider: follow list updated, refreshing connections") |
|
|
|
|
s.updateConnections() |
|
|
|
|
case <-ticker.C: |
|
|
|
|
log.D.F("spider: periodic check triggered") |
|
|
|
|
log.I.F("spider: periodic check triggered") |
|
|
|
|
s.updateConnections() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -251,44 +255,105 @@ func (s *Spider) mainLoop() {
@@ -251,44 +255,105 @@ func (s *Spider) mainLoop() {
|
|
|
|
|
|
|
|
|
|
// updateConnections updates relay connections based on current admin relays and follow lists
|
|
|
|
|
func (s *Spider) updateConnections() { |
|
|
|
|
s.mu.Lock() |
|
|
|
|
defer s.mu.Unlock() |
|
|
|
|
s.mu.RLock() |
|
|
|
|
running := s.running |
|
|
|
|
s.mu.RUnlock() |
|
|
|
|
|
|
|
|
|
if !s.running { |
|
|
|
|
if !running { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Get current admin relays and follow list
|
|
|
|
|
adminRelays := s.getAdminRelays() |
|
|
|
|
followList := s.getFollowList() |
|
|
|
|
if s.getAdminRelays == nil { |
|
|
|
|
log.W.F("spider: getAdminRelays callback is nil") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if s.getFollowList == nil { |
|
|
|
|
log.W.F("spider: getFollowList callback is nil") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Call callbacks with panic recovery
|
|
|
|
|
var adminRelays []string |
|
|
|
|
var followList [][]byte |
|
|
|
|
func() { |
|
|
|
|
defer func() { |
|
|
|
|
if r := recover(); r != nil { |
|
|
|
|
log.E.F("spider: panic in getAdminRelays callback: %v", r) |
|
|
|
|
adminRelays = nil |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
adminRelays = s.getAdminRelays() |
|
|
|
|
}() |
|
|
|
|
func() { |
|
|
|
|
defer func() { |
|
|
|
|
if r := recover(); r != nil { |
|
|
|
|
log.E.F("spider: panic in getFollowList callback: %v", r) |
|
|
|
|
followList = nil |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
followList = s.getFollowList() |
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
log.I.F("spider: updateConnections - admin relays: %d, follow list: %d", len(adminRelays), len(followList)) |
|
|
|
|
if len(adminRelays) > 0 { |
|
|
|
|
log.I.F("spider: admin relays: %v", adminRelays) |
|
|
|
|
} else { |
|
|
|
|
log.I.F("spider: admin relays callback returned empty/nil - checking bootstrap relay configuration") |
|
|
|
|
} |
|
|
|
|
if len(followList) > 0 { |
|
|
|
|
log.D.F("spider: follow list has %d pubkeys", len(followList)) |
|
|
|
|
} else { |
|
|
|
|
log.I.F("spider: follow list callback returned empty/nil - check if admin follow lists have been fetched") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(adminRelays) == 0 || len(followList) == 0 { |
|
|
|
|
log.D.F("spider: no admin relays (%d) or follow list (%d) available", |
|
|
|
|
log.I.F("spider: no admin relays (%d) or follow list (%d) available - cannot create connections", |
|
|
|
|
len(adminRelays), len(followList)) |
|
|
|
|
if len(adminRelays) == 0 { |
|
|
|
|
log.I.F("spider: admin relays callback returned empty list - check if bootstrap relays are configured") |
|
|
|
|
} |
|
|
|
|
if len(followList) == 0 { |
|
|
|
|
log.I.F("spider: follow list callback returned empty list - check if admin follow lists have been fetched") |
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Update connections for current admin relays (filtering out self)
|
|
|
|
|
// Note: We release the mutex before the loop because isSelfRelay() needs to acquire it
|
|
|
|
|
log.I.F("spider: processing %d admin relays (will filter out self-relays)", len(adminRelays)) |
|
|
|
|
currentRelays := make(map[string]bool) |
|
|
|
|
for _, url := range adminRelays { |
|
|
|
|
for i, url := range adminRelays { |
|
|
|
|
log.I.F("spider: checking relay %d/%d: %s", i+1, len(adminRelays), url) |
|
|
|
|
// Check if this relay URL is ourselves
|
|
|
|
|
if s.isSelfRelay(url) { |
|
|
|
|
log.D.F("spider: skipping self-relay: %s", url) |
|
|
|
|
isSelf := s.isSelfRelay(url) |
|
|
|
|
log.D.F("spider: isSelfRelay(%s) = %v", url, isSelf) |
|
|
|
|
if isSelf { |
|
|
|
|
log.I.F("spider: skipping self-relay: %s", url) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
currentRelays[url] = true |
|
|
|
|
|
|
|
|
|
if conn, exists := s.connections[url]; exists { |
|
|
|
|
// Acquire lock to check and modify connections
|
|
|
|
|
s.mu.Lock() |
|
|
|
|
conn, exists := s.connections[url] |
|
|
|
|
s.mu.Unlock() |
|
|
|
|
|
|
|
|
|
if exists { |
|
|
|
|
// Update existing connection
|
|
|
|
|
log.I.F("spider: updating existing connection to %s", url) |
|
|
|
|
conn.updateSubscriptions(followList) |
|
|
|
|
} else { |
|
|
|
|
// Create new connection
|
|
|
|
|
log.I.F("spider: creating new connection to %s", url) |
|
|
|
|
s.createConnection(url, followList) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
log.I.F("spider: processed %d relays, created/updated %d connections", len(adminRelays), len(currentRelays)) |
|
|
|
|
|
|
|
|
|
// Remove connections for relays no longer in admin list
|
|
|
|
|
s.mu.Lock() |
|
|
|
|
for url, conn := range s.connections { |
|
|
|
|
if !currentRelays[url] { |
|
|
|
|
log.I.F("spider: removing connection to %s (no longer in admin relays)", url) |
|
|
|
|
@ -296,6 +361,7 @@ func (s *Spider) updateConnections() {
@@ -296,6 +361,7 @@ func (s *Spider) updateConnections() {
|
|
|
|
|
delete(s.connections, url) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
s.mu.Unlock() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// createConnection creates a new relay connection
|
|
|
|
|
@ -312,7 +378,10 @@ func (s *Spider) createConnection(url string, followList [][]byte) {
@@ -312,7 +378,10 @@ func (s *Spider) createConnection(url string, followList [][]byte) {
|
|
|
|
|
reconnectDelay: ReconnectDelay, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Acquire lock to add connection
|
|
|
|
|
s.mu.Lock() |
|
|
|
|
s.connections[url] = conn |
|
|
|
|
s.mu.Unlock() |
|
|
|
|
|
|
|
|
|
// Start connection in goroutine
|
|
|
|
|
go conn.manage(followList) |
|
|
|
|
|