DHT Deadlockfix
Some checks are pending
CI Pipeline / Run Tests (push) Waiting to run
CI Pipeline / Lint Code (push) Waiting to run
CI Pipeline / Security Scan (push) Waiting to run
CI Pipeline / E2E Tests (push) Blocked by required conditions

This commit is contained in:
Enki 2025-09-02 19:29:45 -07:00
parent 8f485829f7
commit 2b7f44b2d7
3 changed files with 46 additions and 14 deletions

View File

@ -1,6 +1,7 @@
package dht
import (
"context"
"crypto/rand"
"crypto/sha1"
"database/sql"
@ -2217,41 +2218,67 @@ func (d *DHT) queryNodesParallel(candidates []*Node, targetID NodeID, queryType
resultChan := make(chan queryResult, len(candidates))
var wg sync.WaitGroup
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Launch parallel queries
for _, candidate := range candidates {
wg.Add(1)
go func(node *Node) {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
log.Printf("DHT query panic recovered: %v", r)
}
wg.Done()
}()
key := fmt.Sprintf("%s:%d", node.Addr.IP, node.Addr.Port)
queried[key] = true
var discoveredNodes []*Node
if queryType == "find_node" {
nodes, err := d.FindNode(targetID, node.Addr)
if err == nil {
discoveredNodes = nodes
select {
case <-ctx.Done():
return
default:
if queryType == "find_node" {
nodes, err := d.FindNode(targetID, node.Addr)
if err == nil {
discoveredNodes = nodes
}
} else if queryType == "get_peers" {
_, nodes, err := d.GetPeers(targetID[:], node.Addr)
if err == nil && nodes != nil {
discoveredNodes = nodes
}
}
} else if queryType == "get_peers" {
_, nodes, err := d.GetPeers(targetID[:], node.Addr)
if err == nil && nodes != nil {
discoveredNodes = nodes
select {
case resultChan <- queryResult{nodes: discoveredNodes, node: node}:
case <-ctx.Done():
return
}
}
resultChan <- queryResult{nodes: discoveredNodes, node: node}
}(candidate)
}
// Close channel when all queries complete
// Close channel when all queries complete or timeout
go func() {
wg.Wait()
done := make(chan struct{})
go func() {
defer close(done)
wg.Wait()
}()
select {
case <-done:
case <-ctx.Done():
log.Printf("DHT parallel query timeout after 30s")
}
close(resultChan)
}()
// Collect results
// Collect results with timeout
var allNodes []*Node
for result := range resultChan {
if len(result.nodes) > 0 {

View File

@ -107,6 +107,11 @@ func NewUnifiedP2PGateway(config *config.Config, db *sql.DB) *UnifiedP2PGateway
func (g *UnifiedP2PGateway) Initialize() error {
log.Printf("P2P Gateway: Initializing unified P2P system")
// Create database tables
if err := g.CreateP2PTables(); err != nil {
return fmt.Errorf("failed to create P2P database tables: %w", err)
}
// Initialize tracker
if err := g.initializeTracker(); err != nil {
return fmt.Errorf("failed to initialize tracker: %w", err)

Binary file not shown.