mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-24 14:08:13 +08:00
dht/bootstrap: (optional) parallelism + error on peer
This also makes it an Error to find a peer.
This commit is contained in:
@ -342,6 +342,7 @@ func (dht *IpfsDHT) PingRoutine(t time.Duration) {
|
|||||||
|
|
||||||
// Bootstrap builds up list of peers by requesting random peer IDs
|
// Bootstrap builds up list of peers by requesting random peer IDs
|
||||||
func (dht *IpfsDHT) Bootstrap(ctx context.Context, queries int) error {
|
func (dht *IpfsDHT) Bootstrap(ctx context.Context, queries int) error {
|
||||||
|
var merr u.MultiErr
|
||||||
|
|
||||||
randomID := func() peer.ID {
|
randomID := func() peer.ID {
|
||||||
// 16 random bytes is not a valid peer id. it may be fine becuase
|
// 16 random bytes is not a valid peer id. it may be fine becuase
|
||||||
@ -352,18 +353,52 @@ func (dht *IpfsDHT) Bootstrap(ctx context.Context, queries int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bootstrap sequentially, as results will compound
|
// bootstrap sequentially, as results will compound
|
||||||
for i := 0; i < queries; i++ {
|
runQuery := func(ctx context.Context, id peer.ID) {
|
||||||
id := randomID()
|
|
||||||
log.Debugf("Bootstrapping query (%d/%d) to random ID: %s", i, queries, id)
|
|
||||||
p, err := dht.FindPeer(ctx, id)
|
p, err := dht.FindPeer(ctx, id)
|
||||||
if err == routing.ErrNotFound {
|
if err == routing.ErrNotFound {
|
||||||
// this isn't an error. this is precisely what we expect.
|
// this isn't an error. this is precisely what we expect.
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
log.Errorf("Bootstrap peer error: %s", err)
|
merr = append(merr, err)
|
||||||
} else {
|
} else {
|
||||||
// woah, we got a peer under a random id? it _cannot_ be valid.
|
// woah, actually found a peer with that ID? this shouldn't happen normally
|
||||||
log.Errorf("dht seemingly found a peer at a random bootstrap id (%s)...", p)
|
// (as the ID we use is not a real ID). this is an odd error worth logging.
|
||||||
|
err := fmt.Errorf("Bootstrap peer error: Actually FOUND peer. (%s, %s)", id, p)
|
||||||
|
log.Errorf("%s", err)
|
||||||
|
merr = append(merr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sequential := true
|
||||||
|
if sequential {
|
||||||
|
// these should be parallel normally. but can make them sequential for debugging.
|
||||||
|
// note that the core/bootstrap context deadline should be extended too for that.
|
||||||
|
for i := 0; i < queries; i++ {
|
||||||
|
id := randomID()
|
||||||
|
log.Debugf("Bootstrapping query (%d/%d) to random ID: %s", i+1, queries, id)
|
||||||
|
runQuery(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// note on parallelism here: the context is passed in to the queries, so they
|
||||||
|
// **should** exit when it exceeds, making this function exit on ctx cancel.
|
||||||
|
// normally, we should be selecting on ctx.Done() here too, but this gets
|
||||||
|
// complicated to do with WaitGroup, and doesnt wait for the children to exit.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < queries; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
id := randomID()
|
||||||
|
log.Debugf("Bootstrapping query (%d/%d) to random ID: %s", i+1, queries, id)
|
||||||
|
runQuery(ctx, id)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(merr) > 0 {
|
||||||
|
return merr
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
18
util/util.go
18
util/util.go
@ -126,3 +126,21 @@ func GetenvBool(name string) bool {
|
|||||||
v := strings.ToLower(os.Getenv(name))
|
v := strings.ToLower(os.Getenv(name))
|
||||||
return v == "true" || v == "t" || v == "1"
|
return v == "true" || v == "t" || v == "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiErr is a util to return multiple errors
|
||||||
|
type MultiErr []error
|
||||||
|
|
||||||
|
func (m MultiErr) Error() string {
|
||||||
|
if len(m) == 0 {
|
||||||
|
return "no errors"
|
||||||
|
}
|
||||||
|
|
||||||
|
s := "Multiple errors: "
|
||||||
|
for i, e := range m {
|
||||||
|
if i != 0 {
|
||||||
|
s += ", "
|
||||||
|
}
|
||||||
|
s += e.Error()
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user